attribute_defaults 0.1 → 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +3 -0
- data/Gemfile.lock +1 -1
- data/attribute_defaults.gemspec +2 -2
- data/lib/attribute_defaults.rb +136 -0
- data/lib/attribute_defaults/default.rb +19 -0
- data/lib/attribute_defaults/version.rb +3 -0
- data/spec/{active_record/attribute_defaults_spec.rb → attribute_defaults_spec.rb} +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +11 -12
- data/init.rb +0 -1
- data/lib/active_record/attribute_defaults.rb +0 -138
- data/lib/active_record/attribute_defaults/default.rb +0 -21
- data/lib/active_record/attribute_defaults/version.rb +0 -5
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/attribute_defaults.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require File.expand_path("../lib/
|
1
|
+
require File.expand_path("../lib/attribute_defaults/version", __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "attribute_defaults"
|
5
|
-
s.version =
|
5
|
+
s.version = AttributeDefaults::VERSION
|
6
6
|
s.summary = "attribute_defaults-#{s.version}"
|
7
7
|
s.description = "Add default attribute values when creating models."
|
8
8
|
s.authors = ["Jonathan Viney"]
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
require "active_support/core_ext/module/aliasing"
|
3
|
+
require "active_support/core_ext/class/attribute"
|
4
|
+
|
5
|
+
require "attribute_defaults/default"
|
6
|
+
|
7
|
+
module AttributeDefaults
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
alias_method_chain :initialize, :defaults
|
12
|
+
|
13
|
+
class_attribute :attribute_defaults
|
14
|
+
self.attribute_defaults = []
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
# Define default values for attributes on new records. Requires a hash of <tt>attribute => value</tt> pairs, or a single attribute with an associated block.
|
19
|
+
# If the value is a block, it will be called to retrieve the default value.
|
20
|
+
# If the value is a symbol, a method by that name will be called on the object to retrieve the default value.
|
21
|
+
#
|
22
|
+
# The following code demonstrates the different ways default values can be specified. Defaults are applied in the order they are defined.
|
23
|
+
#
|
24
|
+
# class Person < ActiveRecord::Base
|
25
|
+
# defaults :name => 'My name', :city => lambda { 'My city' }
|
26
|
+
#
|
27
|
+
# default :birthdate do |person|
|
28
|
+
# Date.today if person.wants_birthday_today?
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# default :favourite_colour => :default_favourite_colour
|
32
|
+
#
|
33
|
+
# def default_favourite_colour
|
34
|
+
# "Blue"
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# The <tt>defaults</tt> and the <tt>default</tt> methods behave the same way. Use whichever is appropriate.
|
39
|
+
#
|
40
|
+
# The default values are only used if the key is not present in the given attributes.
|
41
|
+
#
|
42
|
+
# p = Person.new
|
43
|
+
# p.name # "My name"
|
44
|
+
# p.city # "My city"
|
45
|
+
#
|
46
|
+
# p = Person.new(:name => nil)
|
47
|
+
# p.name # nil
|
48
|
+
# p.city # "My city"
|
49
|
+
#
|
50
|
+
# == Default values for belongs_to associations
|
51
|
+
#
|
52
|
+
# Default values can also be specified for an association. For instance:
|
53
|
+
#
|
54
|
+
# class Student < ActiveRecord::Base
|
55
|
+
# belongs_to :school
|
56
|
+
# default :school => lambda { School.new }
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# In this scenario, if a school_id was provided in the attributes hash, the default value for the association will be ignored:
|
60
|
+
#
|
61
|
+
# s = Student.new
|
62
|
+
# s.school # => #<School: ...>
|
63
|
+
#
|
64
|
+
# s = Student.new(:school_id => nil)
|
65
|
+
# s.school # => nil
|
66
|
+
#
|
67
|
+
# Similarly, if a default value is specified for the foreign key and an object for the association is provided, the default foreign key is ignored.
|
68
|
+
def defaults(defaults, &block)
|
69
|
+
default_objects = case
|
70
|
+
when defaults.is_a?(Hash)
|
71
|
+
defaults.map { |attribute, value| Default.new(attribute, value) }
|
72
|
+
|
73
|
+
when defaults.is_a?(Symbol) && block
|
74
|
+
Default.new(defaults, block)
|
75
|
+
|
76
|
+
else
|
77
|
+
raise "pass either a hash of attribute/value pairs, or a single attribute with a block"
|
78
|
+
end
|
79
|
+
|
80
|
+
self.attribute_defaults += Array.wrap(default_objects)
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :default, :defaults
|
84
|
+
end
|
85
|
+
|
86
|
+
module InstanceMethods
|
87
|
+
if ActiveRecord::VERSION::STRING >= "3.1"
|
88
|
+
def initialize_with_defaults(attributes = nil, options = {})
|
89
|
+
initialize_without_defaults(attributes, options) do |record|
|
90
|
+
record.apply_default_attribute_values(attributes)
|
91
|
+
yield record if block_given?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
else
|
95
|
+
def initialize_with_defaults(attributes = nil)
|
96
|
+
initialize_without_defaults(attributes) do |record|
|
97
|
+
record.apply_default_attribute_values(attributes)
|
98
|
+
yield record if block_given?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def apply_default_attribute_values(specific_attributes)
|
104
|
+
specific_attributes = (specific_attributes || {}).stringify_keys
|
105
|
+
|
106
|
+
# Rails 3.1 deprecates #primary_key_name in favour of :foreign_key
|
107
|
+
foreign_key_method = if ActiveRecord::VERSION::STRING >= "3.1"
|
108
|
+
:foreign_key
|
109
|
+
else
|
110
|
+
:primary_key_name
|
111
|
+
end
|
112
|
+
|
113
|
+
self.class.attribute_defaults.each do |default|
|
114
|
+
next if specific_attributes.include?(default.attribute)
|
115
|
+
|
116
|
+
# Ignore a default value for association_id if association has been specified
|
117
|
+
reflection = self.class.reflections[default.attribute.to_sym]
|
118
|
+
if reflection and reflection.macro == :belongs_to and specific_attributes.include?(reflection.send(foreign_key_method).to_s)
|
119
|
+
next
|
120
|
+
end
|
121
|
+
|
122
|
+
# Ignore a default value for association if association_id has been specified
|
123
|
+
reflection = self.class.reflections.values.find { |r| r.macro == :belongs_to && r.send(foreign_key_method).to_s == default.attribute }
|
124
|
+
if reflection and specific_attributes.include?(reflection.name.to_s)
|
125
|
+
next
|
126
|
+
end
|
127
|
+
|
128
|
+
send("#{default.attribute}=", default.value(self))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class ActiveRecord::Base
|
135
|
+
include AttributeDefaults
|
136
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module AttributeDefaults
|
2
|
+
class Default
|
3
|
+
attr_reader :attribute
|
4
|
+
|
5
|
+
def initialize(attribute, value)
|
6
|
+
@attribute, @value = attribute.to_s, value
|
7
|
+
end
|
8
|
+
|
9
|
+
def value(record)
|
10
|
+
if @value.is_a?(Symbol)
|
11
|
+
record.send(@value)
|
12
|
+
elsif @value.respond_to?(:call)
|
13
|
+
@value.call(record)
|
14
|
+
else
|
15
|
+
@value.duplicable? ? @value.dup : @value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,7 @@ require "rspec"
|
|
5
5
|
require "active_record"
|
6
6
|
require "active_record/base"
|
7
7
|
|
8
|
-
require File.expand_path("../../lib/
|
8
|
+
require File.expand_path("../../lib/attribute_defaults", __FILE__)
|
9
9
|
|
10
10
|
ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + "/database.yml"))
|
11
11
|
ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/debug.log")
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attribute_defaults
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 2
|
9
|
+
version: "0.2"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jonathan Viney
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-07-
|
17
|
+
date: 2011-07-03 00:00:00 +12:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -75,11 +75,10 @@ files:
|
|
75
75
|
- LICENSE
|
76
76
|
- Readme.md
|
77
77
|
- attribute_defaults.gemspec
|
78
|
-
-
|
79
|
-
- lib/
|
80
|
-
- lib/
|
81
|
-
-
|
82
|
-
- spec/active_record/attribute_defaults_spec.rb
|
78
|
+
- lib/attribute_defaults.rb
|
79
|
+
- lib/attribute_defaults/default.rb
|
80
|
+
- lib/attribute_defaults/version.rb
|
81
|
+
- spec/attribute_defaults_spec.rb
|
83
82
|
- spec/database.yml
|
84
83
|
- spec/schema.rb
|
85
84
|
- spec/spec_helper.rb
|
@@ -113,9 +112,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
112
|
requirements: []
|
114
113
|
|
115
114
|
rubyforge_project:
|
116
|
-
rubygems_version: 1.
|
115
|
+
rubygems_version: 1.3.7
|
117
116
|
signing_key:
|
118
117
|
specification_version: 3
|
119
|
-
summary: attribute_defaults-0.
|
118
|
+
summary: attribute_defaults-0.2
|
120
119
|
test_files: []
|
121
120
|
|
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "active_record/attribute_defaults"
|
@@ -1,138 +0,0 @@
|
|
1
|
-
require "active_support/concern"
|
2
|
-
require "active_support/core_ext/module/aliasing"
|
3
|
-
require "active_support/core_ext/class/attribute"
|
4
|
-
|
5
|
-
require "active_record/attribute_defaults/default"
|
6
|
-
|
7
|
-
module ActiveRecord
|
8
|
-
module AttributeDefaults
|
9
|
-
extend ActiveSupport::Concern
|
10
|
-
|
11
|
-
included do
|
12
|
-
alias_method_chain :initialize, :defaults
|
13
|
-
|
14
|
-
class_attribute :attribute_defaults
|
15
|
-
self.attribute_defaults = []
|
16
|
-
end
|
17
|
-
|
18
|
-
module ClassMethods
|
19
|
-
# Define default values for attributes on new records. Requires a hash of <tt>attribute => value</tt> pairs, or a single attribute with an associated block.
|
20
|
-
# If the value is a block, it will be called to retrieve the default value.
|
21
|
-
# If the value is a symbol, a method by that name will be called on the object to retrieve the default value.
|
22
|
-
#
|
23
|
-
# The following code demonstrates the different ways default values can be specified. Defaults are applied in the order they are defined.
|
24
|
-
#
|
25
|
-
# class Person < ActiveRecord::Base
|
26
|
-
# defaults :name => 'My name', :city => lambda { 'My city' }
|
27
|
-
#
|
28
|
-
# default :birthdate do |person|
|
29
|
-
# Date.today if person.wants_birthday_today?
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# default :favourite_colour => :default_favourite_colour
|
33
|
-
#
|
34
|
-
# def default_favourite_colour
|
35
|
-
# "Blue"
|
36
|
-
# end
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# The <tt>defaults</tt> and the <tt>default</tt> methods behave the same way. Use whichever is appropriate.
|
40
|
-
#
|
41
|
-
# The default values are only used if the key is not present in the given attributes.
|
42
|
-
#
|
43
|
-
# p = Person.new
|
44
|
-
# p.name # "My name"
|
45
|
-
# p.city # "My city"
|
46
|
-
#
|
47
|
-
# p = Person.new(:name => nil)
|
48
|
-
# p.name # nil
|
49
|
-
# p.city # "My city"
|
50
|
-
#
|
51
|
-
# == Default values for belongs_to associations
|
52
|
-
#
|
53
|
-
# Default values can also be specified for an association. For instance:
|
54
|
-
#
|
55
|
-
# class Student < ActiveRecord::Base
|
56
|
-
# belongs_to :school
|
57
|
-
# default :school => lambda { School.new }
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# In this scenario, if a school_id was provided in the attributes hash, the default value for the association will be ignored:
|
61
|
-
#
|
62
|
-
# s = Student.new
|
63
|
-
# s.school # => #<School: ...>
|
64
|
-
#
|
65
|
-
# s = Student.new(:school_id => nil)
|
66
|
-
# s.school # => nil
|
67
|
-
#
|
68
|
-
# Similarly, if a default value is specified for the foreign key and an object for the association is provided, the default foreign key is ignored.
|
69
|
-
def defaults(defaults, &block)
|
70
|
-
default_objects = case
|
71
|
-
when defaults.is_a?(Hash)
|
72
|
-
defaults.map { |attribute, value| Default.new(attribute, value) }
|
73
|
-
|
74
|
-
when defaults.is_a?(Symbol) && block
|
75
|
-
Default.new(defaults, block)
|
76
|
-
|
77
|
-
else
|
78
|
-
raise "pass either a hash of attribute/value pairs, or a single attribute with a block"
|
79
|
-
end
|
80
|
-
|
81
|
-
self.attribute_defaults += Array.wrap(default_objects)
|
82
|
-
end
|
83
|
-
|
84
|
-
alias_method :default, :defaults
|
85
|
-
end
|
86
|
-
|
87
|
-
module InstanceMethods
|
88
|
-
if ActiveRecord::VERSION::STRING >= "3.1"
|
89
|
-
def initialize_with_defaults(attributes = nil, options = {})
|
90
|
-
initialize_without_defaults(attributes, options) do |record|
|
91
|
-
record.apply_default_attribute_values(attributes)
|
92
|
-
yield record if block_given?
|
93
|
-
end
|
94
|
-
end
|
95
|
-
else
|
96
|
-
def initialize_with_defaults(attributes = nil)
|
97
|
-
initialize_without_defaults(attributes) do |record|
|
98
|
-
record.apply_default_attribute_values(attributes)
|
99
|
-
yield record if block_given?
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def apply_default_attribute_values(specific_attributes)
|
105
|
-
specific_attributes = (specific_attributes || {}).stringify_keys
|
106
|
-
|
107
|
-
# Rails 3.1 deprecates #primary_key_name in favour of :foreign_key
|
108
|
-
foreign_key_method = if ActiveRecord::VERSION::STRING >= "3.1"
|
109
|
-
:foreign_key
|
110
|
-
else
|
111
|
-
:primary_key_name
|
112
|
-
end
|
113
|
-
|
114
|
-
self.class.attribute_defaults.each do |default|
|
115
|
-
next if specific_attributes.include?(default.attribute)
|
116
|
-
|
117
|
-
# Ignore a default value for association_id if association has been specified
|
118
|
-
reflection = self.class.reflections[default.attribute.to_sym]
|
119
|
-
if reflection and reflection.macro == :belongs_to and specific_attributes.include?(reflection.send(foreign_key_method).to_s)
|
120
|
-
next
|
121
|
-
end
|
122
|
-
|
123
|
-
# Ignore a default value for association if association_id has been specified
|
124
|
-
reflection = self.class.reflections.values.find { |r| r.macro == :belongs_to && r.send(foreign_key_method).to_s == default.attribute }
|
125
|
-
if reflection and specific_attributes.include?(reflection.name.to_s)
|
126
|
-
next
|
127
|
-
end
|
128
|
-
|
129
|
-
send("#{default.attribute}=", default.value(self))
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
class ActiveRecord::Base
|
137
|
-
include ActiveRecord::AttributeDefaults
|
138
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module AttributeDefaults
|
3
|
-
class Default
|
4
|
-
attr_reader :attribute
|
5
|
-
|
6
|
-
def initialize(attribute, value)
|
7
|
-
@attribute, @value = attribute.to_s, value
|
8
|
-
end
|
9
|
-
|
10
|
-
def value(record)
|
11
|
-
if @value.is_a?(Symbol)
|
12
|
-
record.send(@value)
|
13
|
-
elsif @value.respond_to?(:call)
|
14
|
-
@value.call(record)
|
15
|
-
else
|
16
|
-
@value.duplicable? ? @value.dup : @value
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|