attr_default 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.sqlite3
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ test/test.sqlite3
20
+ nbproject
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'hobosupport', '0.9.103', :path => '../web/vendor/gems/hobosupport-0.9.103'
4
+ gem 'hobofields', '0.9.103', :path => '../web/vendor/gems/hobofields-0.9.103'
5
+
6
+ # Specify your gem's dependencies in attr_default.gemspec
7
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Colin Kelley, RingRevenue
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,106 @@
1
+ = AttrDefault
2
+
3
+ Dynamic Ruby defaults for ActiveRecord attributes.
4
+ These are lazy evaluated just in time: when first accessed, or just before validation or save.
5
+ This allows dynamic defaults to depend on attributes that are assigned after initialization, or on other dynamic defaults.
6
+
7
+ Example:
8
+
9
+ class User < ActiveRecord::Base
10
+ attr_default :middle_name, ''
11
+ attr_default :guid, lambda { GuidGenerator.new }
12
+ attr_default :managed, lambda { organization.managed? }
13
+
14
+ belongs_to :organization
15
+ ...
16
+ end
17
+
18
+ == Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'attr_default'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install attr_default
31
+
32
+ == Usage
33
+
34
+ require 'attr_default'
35
+
36
+ This makes the +attr_default+ macro available to all objects derived fromActiveRecord::Base.
37
+
38
+ === The attr_default Macro
39
+
40
+ The +attr_default+ macro takes 2 arguments:
41
+
42
+ [attr_name] The name of the attribute, given as a symbol or string.
43
+ [default] The default value to use, either as a simple value or a Proc. If a Proc, attr_default will call it in the context of the object.
44
+ This makes it convenient for dynamic defaults to be computed based on other attributes or associations.
45
+
46
+ +attr_default+ can be used for persistent or non-persistent attributes.
47
+
48
+ === Timing of Default Computation
49
+
50
+ Defaults are lazy computed, just in time, whenever the first of these happens:
51
+
52
+ * The attribute is read.
53
+ * The object's before_validation callback is called.
54
+ * The object's before_save callback is called.
55
+
56
+ This allows dynamic defaults to depend on other attributes that may be assigned after the initializer, and even other dynamic defaults.
57
+ For example:
58
+
59
+ class User < ActiveRecord::Base
60
+ attr_default :first_name, 'First'
61
+ attr_default :last_name, 'Last'
62
+ attr_default :name_addr, lambda { "#{full_name} <#{email}>" }
63
+
64
+ def full_name
65
+ [first_name, middle_name, last_name].select { |name| !name.blank? } * ' '
66
+ end
67
+ end
68
+
69
+ user1 = User.create :email => 'joe@yahoo.com', :first_name => 'Joe'
70
+ user1.name_addr # => "Joe Last <joe@yahoo.com>"
71
+
72
+ user2 = User.create :email => 'jane@yahoo.com'
73
+ user2.last_name = 'Doe'
74
+ user2.name_addr # => "First Doe <jane@yahoo.com>"
75
+
76
+ === Use with Hobofields
77
+
78
+ With Hobofields, defaults can be set using the +:ruby_default+ option:
79
+
80
+ class User < ActiveRecord::Base
81
+ fields do
82
+ first_name :string, :ruby_default => 'First'
83
+ last_name :string, :ruby_default => 'Last'
84
+ email :string
85
+ name_addr :string, :ruby_default => lambda { "#{full_name} <#{email}>" }
86
+ ...
87
+ end
88
+
89
+ def full_name
90
+ [first_name, middle_name, last_name].select { |name| name unless name.blank? } * ' '
91
+ end
92
+ end
93
+
94
+ The +:default+ option controls the default in SQL, unless a Ruby Proc is given in which case it is treated as +:ruby_default+.
95
+
96
+ === Interaction with +clone+
97
+
98
+ Dynamic defaults work with +clone+, following the same timing given above.
99
+
100
+ == Contributing
101
+
102
+ 1. Fork it
103
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
104
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
105
+ 4. Push to the branch (`git push origin my-new-feature`)
106
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ task :default => :test
5
+
6
+ desc "Run unit tests."
7
+ task :test do
8
+ ruby "test/test_attr_default.rb"
9
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../lib/attr_default/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.add_dependency 'rake'
5
+ gem.add_dependency 'rails'
6
+ gem.add_development_dependency 'sqlite3'
7
+ gem.add_development_dependency 'hobofields'
8
+ gem.authors = ["Colin Kelley", "Nick Burwell"]
9
+ gem.email = ["colindkelley@gmail.com"]
10
+ gem.description = %q{Dynamic Ruby defaults for ActiveRecord attributes}
11
+ gem.summary = %q{Dynamic Ruby defaults for ActiveRecord attributes. These are lazy evaluated just in time: when first accessed, or just before validation or save. This allows dynamic defaults to depend on attributes that are assigned after initialization, or on other dynamic defaults.}
12
+ gem.homepage = ""
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/.*\.rb})
17
+ gem.name = "attr_default"
18
+ gem.require_paths = ["lib"]
19
+ gem.version = AttrDefault::VERSION
20
+ end
@@ -0,0 +1,88 @@
1
+ module AttrDefault
2
+ module ClassMethods
3
+ def attr_default attr_name, default
4
+ if !method_defined?(:_attr_default_set)
5
+ include AttrDefault
6
+ end
7
+
8
+ attr_name = attr_name.to_s
9
+ define_method attr_name do
10
+ if new_record? && !@_attr_defaults_set_from_clone && !_attr_default_set[attr_name]
11
+ default_value = Proc === default ? instance_eval(&default) : default.dup
12
+ send "#{attr_name}=", default_value
13
+ end
14
+ read_attribute_with_fixups( attr_name )
15
+ end
16
+
17
+ define_method "#{attr_name}=" do |*args|
18
+ _attr_default_set[attr_name] = true
19
+ write_attribute_with_fixups( attr_name, args )
20
+ end
21
+
22
+ touch_proc = lambda { |obj| obj.send(attr_name); true }
23
+ before_validation touch_proc
24
+ before_save touch_proc
25
+ end
26
+
27
+ # Hobo Fields field declaration
28
+ def field_added(name, type, args, options)
29
+ if (default = options[:ruby_default]) && Proc === default
30
+ attr_default name, default
31
+ elsif (default = options[:default]) && Proc === default
32
+ attr_default name, default
33
+ options.delete(:default)
34
+ options[:ruby_default] = default
35
+ end
36
+ end
37
+ end
38
+
39
+ def _attr_default_set
40
+ @_attr_default_set ||= {}
41
+ end
42
+
43
+ def read_attribute_with_fixups(attr_name)
44
+ if needs_time_zone_fixup?(attr_name)
45
+ cached = @attributes_cache[attr_name] and return cached
46
+ time = read_attribute(attr_name)
47
+ @attributes_cache[attr_name] = time.acts_like?(:time) ? time.in_time_zone : time
48
+ else
49
+ read_attribute(attr_name)
50
+ end
51
+ end
52
+
53
+ def write_attribute_with_fixups(attr_name, args)
54
+ if needs_time_zone_fixup?(attr_name)
55
+ time = args.first
56
+ unless time.acts_like?(:time)
57
+ time = time.is_a?(String) ? Time.zone.parse(time) : time.to_time rescue time
58
+ end
59
+ time = time.in_time_zone rescue nil if time
60
+ write_attribute(attr_name, time)
61
+ else
62
+ write_attribute(attr_name, *args)
63
+ end
64
+ end
65
+
66
+ def needs_time_zone_fixup?(attr_name)
67
+ self.class.send(:create_time_zone_conversion_attribute?, attr_name, self.class.columns_hash[attr_name])
68
+ end
69
+
70
+ def clone
71
+ result = super
72
+ result.created_at = nil unless !result.class.columns_hash.has_key?('created_at')
73
+ result.updated_at = nil unless !result.class.columns_hash.has_key?('updated_at')
74
+ if self.new_record?
75
+ result.instance_variable_set(:@_attr_default_set, self._attr_default_set.dup)
76
+ else
77
+ result.instance_variable_set(:@_attr_defaults_set_from_clone, true)
78
+ end
79
+ result
80
+ end
81
+ end
82
+
83
+ if defined?(Rails::Railtie)
84
+ require 'attr_default/railtie'
85
+ else
86
+ # Rails 2 initialization
87
+ ActiveRecord::Base.extend(AttrDefault::ClassMethods)
88
+ end
@@ -0,0 +1,3 @@
1
+ module AttrDefault
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,255 @@
1
+ WANT_RAILS_VERSION = "~> #{ENV.fetch('WANT_RAILS_VERSION', '2.3.4')}"
2
+
3
+ require 'rubygems'
4
+ gem 'rails', WANT_RAILS_VERSION
5
+ gem 'activerecord', WANT_RAILS_VERSION
6
+ begin
7
+ require 'rails/railtie'
8
+ rescue LoadError
9
+ end
10
+ require 'active_record'
11
+ ActiveRecord::ActiveRecordError # work-around from https://rails.lighthouseapp.com/projects/8994/tickets/2577-when-using-activerecordassociations-outside-of-rails-a-nameerror-is-thrown
12
+ require 'test/unit'
13
+ require 'active_support/dependencies'
14
+ require 'active_support/core_ext/logger'
15
+ require 'hobofields' if ENV['INCLUDE_HOBO']
16
+
17
+ $LOAD_PATH.unshift File.expand_path("lib", File.dirname(__FILE__))
18
+ require 'attr_default'
19
+ Dir.chdir(File.dirname(__FILE__))
20
+
21
+ if RUBY_PLATFORM == "java"
22
+ database_adapter = "jdbcsqlite3"
23
+ else
24
+ database_adapter = "sqlite3"
25
+ end
26
+
27
+ File.unlink('test.sqlite3') rescue nil
28
+ ActiveRecord::Base.logger = Logger.new(STDERR)
29
+ ActiveRecord::Base.logger.level = Logger::WARN
30
+ ActiveRecord::Base.establish_connection(
31
+ :adapter => database_adapter,
32
+ :database => 'test.sqlite3'
33
+ )
34
+
35
+ ActiveRecord::Base.connection.create_table(:test_users, :force => true) do |t|
36
+ t.string :first_name
37
+ t.string :last_name
38
+ t.boolean :managed
39
+ t.timestamp :timestamp
40
+ end
41
+
42
+ ActiveRecord::Base.connection.create_table(:test_numbers, :force => true) do |t|
43
+ t.string :type
44
+ t.integer :test_user_id
45
+ t.integer :number
46
+ t.boolean :managed
47
+ t.timestamp :created_at
48
+ end
49
+
50
+ if defined?(Rails::Railtie)
51
+ DefaultValueFor.initialize_railtie
52
+ DefaultValueFor.initialize_active_record_extensions
53
+ end
54
+
55
+ class TestUser < ActiveRecord::Base
56
+ attr_accessor :password
57
+ attr_default :password, '<none>'
58
+
59
+ if ENV['INCLUDE_HOBO']
60
+ fields do
61
+ first_name :string, :default => '', :ruby_default => 'John'
62
+ last_name :string, :default => 'Doe'
63
+ timestamp :timestamp, :default => lambda { (Time.zone || ActiveSupport::TimeZone['Pacific Time (US & Canada)']).now }
64
+ end
65
+ else
66
+ attr_default :first_name, 'John'
67
+ attr_default :last_name, 'Doe'
68
+ attr_default :timestamp, lambda { (Time.zone || ActiveSupport::TimeZone['Pacific Time (US & Canada)']).now }
69
+ end
70
+
71
+ has_many :test_numbers
72
+ has_many :test_numbers_subclass, :class_name => 'TestNumberSubclass'
73
+ end
74
+
75
+ class TestNumber < ActiveRecord::Base
76
+ if ENV['INCLUDE_HOBO']
77
+ fields do
78
+ managed :boolean, :default => lambda { test_user.managed }
79
+ end
80
+ else
81
+ attr_default :managed, lambda { test_user.managed }
82
+ end
83
+
84
+ belongs_to :test_user
85
+ end
86
+
87
+ class TestNumberSubclass < TestNumber
88
+ if ENV['INCLUDE_HOBO']
89
+ fields do
90
+ managed :boolean, :default => lambda { false }
91
+ end
92
+ else
93
+ attr_default :managed, lambda { false }
94
+ end
95
+ end
96
+
97
+
98
+ class AttrDefaultTest < Test::Unit::TestCase
99
+ def define_model_class(name = "TestClass", parent_class_name = "ActiveRecord::Base", &block)
100
+ Object.send(:remove_const, name) rescue nil
101
+ eval("class #{name} < #{parent_class_name}; end", TOPLEVEL_BINDING)
102
+ klass = eval(name, TOPLEVEL_BINDING)
103
+ klass.class_eval do
104
+ if respond_to?(:table_name=)
105
+ self.table_name = 'numbers'
106
+ else
107
+ set_table_name 'numbers'
108
+ end
109
+ end
110
+ klass.class_eval(&block) if block_given?
111
+ end
112
+
113
+ def test_use_default_if_not_set
114
+ u = TestUser.new
115
+ assert_equal nil, u.read_attribute(:last_name)
116
+ assert_equal "Doe", u.last_name
117
+ end
118
+
119
+ def test_return_the_ActiveRecord_native_type_not_the_lambda_type
120
+ u = TestUser.new
121
+ assert_equal 'ActiveSupport::TimeWithZone', u.timestamp.class.name
122
+ begin
123
+ old_time_zone, Time.zone = Time.zone, 'Central Time (US & Canada)'
124
+ u = TestUser.new
125
+ assert_equal 'ActiveSupport::TimeWithZone', u.timestamp.class.name
126
+ assert_match /Central Time/, u.timestamp.time_zone.to_s
127
+ ensure
128
+ Time.zone = old_time_zone
129
+ end
130
+ end
131
+
132
+ def test_allow_an_override_to_be_specified
133
+ u = TestUser.new( :last_name => "override" )
134
+ assert_equal "override", u.read_attribute(:last_name)
135
+ assert_equal "override", u.last_name
136
+ end
137
+
138
+ if ENV['INCLUDE_HOBO']
139
+ def test_hobo_allow_default_and_ruby_default
140
+ u = TestUser.new
141
+ assert_equal nil, u.read_attribute(:first_name)
142
+ assert_equal "", TestUser.field_specs['first_name'].options[:default]
143
+ assert_equal "John", TestUser.field_specs['first_name'].options[:ruby_default].call
144
+ assert_equal "John", u.first_name
145
+ end
146
+ end
147
+
148
+ def test_handle_mutating_the_default_string
149
+ u = TestUser.new
150
+ u2 = TestUser.new
151
+
152
+ assert_equal "Doe", u2.last_name
153
+ u.last_name.upcase!
154
+ assert_equal "Doe", u2.last_name # should not be DOE
155
+
156
+ u3 = TestUser.new
157
+ assert_equal "Doe", u3.last_name
158
+ end
159
+
160
+ def test_use_default_when_saved_if_not_touched
161
+ user = TestUser.create! :managed => true
162
+ number = user.test_numbers.build
163
+
164
+ number.save!
165
+ number.reload
166
+ assert_equal true, number.read_attribute(:managed)
167
+ assert_equal true, number.managed
168
+ end
169
+
170
+ def test_clone_touched_state_when_cloned_before_save_new_record_true
171
+ u = TestUser.new :first_name => 'John', :last_name => 'Doe'
172
+ u.last_name = 'overridden'
173
+ u2 = u.clone
174
+ assert_equal 'overridden', u2.read_attribute(:last_name)
175
+ assert_equal 'overridden', u2.last_name
176
+ end
177
+
178
+ def test_clone_touched_state_when_cloned_after_save_new_record_false
179
+ u = TestUser.new :first_name => 'John', :last_name => 'Doe'
180
+ u.last_name = 'overridden'
181
+ u2 = u.clone
182
+ u2.save!
183
+ u.save!
184
+ assert u.clone.instance_variable_get(:@_attr_defaults_set_from_clone)
185
+ assert_equal 'overridden', u.clone.last_name
186
+ ufind = TestUser.find(u.id)
187
+ u3 = ufind.clone
188
+ assert_equal 'overridden', u3.read_attribute(:last_name), u3.attributes.inspect
189
+ assert_equal 'overridden', u3.last_name
190
+ u3.save!
191
+ assert_equal 'overridden', u2.read_attribute(:last_name)
192
+ assert_equal 'overridden', u2.last_name
193
+ assert_equal 'overridden', u3.read_attribute(:last_name)
194
+ assert_equal 'overridden', u3.last_name
195
+ end
196
+
197
+ def test_use_default_when_saved_if_not_touched_and_validation_turned_off
198
+ user = TestUser.create! :managed => true
199
+ number = user.test_numbers.build :number => 42
200
+
201
+ # not touched or saved yet, still empty
202
+ assert_equal nil, number.read_attribute(:managed)
203
+
204
+ number.save(false)
205
+
206
+ # now it should be true
207
+ assert_equal true, number.read_attribute(:managed)
208
+ assert_equal true, number.managed
209
+ end
210
+
211
+ def test_use_value_set_on_object_even_when_first_loaded_from_db
212
+ user = TestUser.create! :managed => true
213
+ number = user.test_numbers.create! :number => 42, :managed => false
214
+ number_find = TestNumber.find(number.id)
215
+ assert_equal false, number_find.managed
216
+ end
217
+
218
+ [false, true].each do |user_managed|
219
+ define_method "test_default_#{user_managed}_and_param_not_specified" do
220
+ user = TestUser.create! :managed => user_managed
221
+ number = user.test_numbers.build
222
+ assert_equal user_managed, number.managed
223
+ end
224
+
225
+ define_method "test_default_#{user_managed}_and_#{!user_managed}_specified" do
226
+ user = TestUser.create! :managed => true
227
+ number = user.test_numbers.build :managed => !user_managed
228
+ assert_equal !user_managed, number.managed
229
+ end
230
+ end
231
+
232
+ def test_allow_subclass_to_override_the_default
233
+ user = TestUser.create! :managed => true
234
+ number = user.test_numbers.new
235
+ assert_equal true, number.managed
236
+ number_subclass = user.test_numbers_subclass.new
237
+ assert_equal false, number_subclass.managed
238
+ end
239
+
240
+ def test_non_persistent_use_default_if_not_set
241
+ user = TestUser.new
242
+ assert_equal "<none>", user.password
243
+ end
244
+
245
+ def test_non_persistent_use_value_if_set_in_initialize
246
+ user = TestUser.new :password => "supersecret"
247
+ assert_equal "supersecret", user.password
248
+ end
249
+
250
+ def test_non_persistent_use_value_if_set_after_initialize
251
+ user = TestUser.new
252
+ user.password = "supersecret"
253
+ assert_equal "supersecret", user.password
254
+ end
255
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: attr_default
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
+ platform: ruby
11
+ authors:
12
+ - Colin Kelley
13
+ - Nick Burwell
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-06-10 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rake
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rails
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ type: :runtime
44
+ version_requirements: *id002
45
+ - !ruby/object:Gem::Dependency
46
+ name: sqlite3
47
+ prerelease: false
48
+ requirement: &id003 !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ type: :development
56
+ version_requirements: *id003
57
+ - !ruby/object:Gem::Dependency
58
+ name: hobofields
59
+ prerelease: false
60
+ requirement: &id004 !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ type: :development
68
+ version_requirements: *id004
69
+ description: Dynamic Ruby defaults for ActiveRecord attributes
70
+ email:
71
+ - colindkelley@gmail.com
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files: []
77
+
78
+ files:
79
+ - .gitignore
80
+ - Gemfile
81
+ - LICENSE
82
+ - README.rdoc
83
+ - Rakefile
84
+ - attr_default.gemspec
85
+ - lib/attr_default.rb
86
+ - lib/attr_default/version.rb
87
+ - test/test_attr_default.rb
88
+ has_rdoc: true
89
+ homepage: ""
90
+ licenses: []
91
+
92
+ post_install_message:
93
+ rdoc_options: []
94
+
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.3.6
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: "Dynamic Ruby defaults for ActiveRecord attributes. These are lazy evaluated just in time: when first accessed, or just before validation or save. This allows dynamic defaults to depend on attributes that are assigned after initialization, or on other dynamic defaults."
118
+ test_files:
119
+ - test/test_attr_default.rb