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 CHANGED
@@ -1,2 +1,5 @@
1
1
  source "http://rubygems.org"
2
2
  gemspec
3
+
4
+ gem "rspec"
5
+ gem "mysql2", "< 0.3"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attribute_defaults (0.1)
4
+ attribute_defaults (0.2)
5
5
  activerecord (>= 3)
6
6
 
7
7
  GEM
@@ -1,8 +1,8 @@
1
- require File.expand_path("../lib/active_record/attribute_defaults/version", __FILE__)
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 = ActiveRecord::AttributeDefaults::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
@@ -0,0 +1,3 @@
1
+ module AttributeDefaults
2
+ VERSION = "0.2"
3
+ end
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- describe "active_record/attribute_defaults" do
3
+ describe "attribute_defaults" do
4
4
  it "should supply defaults for a new record" do
5
5
  p = Person.new
6
6
 
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/active_record/attribute_defaults", __FILE__)
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: 9
5
- prerelease:
4
+ hash: 15
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
- version: "0.1"
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-02 00:00:00 +12:00
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
- - init.rb
79
- - lib/active_record/attribute_defaults.rb
80
- - lib/active_record/attribute_defaults/default.rb
81
- - lib/active_record/attribute_defaults/version.rb
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.6.2
115
+ rubygems_version: 1.3.7
117
116
  signing_key:
118
117
  specification_version: 3
119
- summary: attribute_defaults-0.1
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
@@ -1,5 +0,0 @@
1
- module ActiveRecord
2
- module AttributeDefaults
3
- VERSION = "0.1"
4
- end
5
- end