activemodel 3.0.0.beta4 → 3.0.pre

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.
Files changed (39) hide show
  1. data/CHANGELOG +1 -39
  2. data/MIT-LICENSE +1 -1
  3. data/README +16 -200
  4. data/lib/active_model.rb +19 -28
  5. data/lib/active_model/attribute_methods.rb +27 -142
  6. data/lib/active_model/conversion.rb +1 -37
  7. data/lib/active_model/dirty.rb +12 -51
  8. data/lib/active_model/errors.rb +22 -146
  9. data/lib/active_model/lint.rb +14 -48
  10. data/lib/active_model/locale/en.yml +23 -26
  11. data/lib/active_model/naming.rb +5 -41
  12. data/lib/active_model/observing.rb +16 -35
  13. data/lib/active_model/serialization.rb +0 -57
  14. data/lib/active_model/serializers/json.rb +8 -13
  15. data/lib/active_model/serializers/xml.rb +123 -63
  16. data/lib/active_model/state_machine.rb +70 -0
  17. data/lib/active_model/state_machine/event.rb +62 -0
  18. data/lib/active_model/state_machine/machine.rb +75 -0
  19. data/lib/active_model/state_machine/state.rb +47 -0
  20. data/lib/active_model/state_machine/state_transition.rb +40 -0
  21. data/lib/active_model/test_case.rb +2 -0
  22. data/lib/active_model/validations.rb +62 -125
  23. data/lib/active_model/validations/acceptance.rb +18 -23
  24. data/lib/active_model/validations/confirmation.rb +10 -14
  25. data/lib/active_model/validations/exclusion.rb +13 -15
  26. data/lib/active_model/validations/format.rb +24 -26
  27. data/lib/active_model/validations/inclusion.rb +13 -15
  28. data/lib/active_model/validations/length.rb +65 -61
  29. data/lib/active_model/validations/numericality.rb +58 -76
  30. data/lib/active_model/validations/presence.rb +8 -8
  31. data/lib/active_model/validations/with.rb +22 -90
  32. data/lib/active_model/validations_repair_helper.rb +35 -0
  33. data/lib/active_model/version.rb +2 -3
  34. metadata +19 -63
  35. data/lib/active_model/callbacks.rb +0 -134
  36. data/lib/active_model/railtie.rb +0 -2
  37. data/lib/active_model/translation.rb +0 -60
  38. data/lib/active_model/validations/validates.rb +0 -108
  39. data/lib/active_model/validator.rb +0 -183
data/CHANGELOG CHANGED
@@ -1,42 +1,4 @@
1
- *Rails 3.0.0 [beta 4] (June 8th, 2010)*
2
-
3
- * JSON supports a custom root option: to_json(:root => 'custom') #4515 [Jatinder Singh]
4
-
5
-
6
- *Rails 3.0.0 [beta 3] (April 13th, 2010)*
7
-
8
- * No changes
9
-
10
-
11
- *Rails 3.0.0 [beta 2] (April 1st, 2010)*
12
-
13
- * #new_record? and #destroyed? were removed from ActiveModel::Lint. Use
14
- persisted? instead. A model is persisted if it's not a new_record? and it was
15
- not destroyed? [MG]
16
-
17
- * Added validations reflection in ActiveModel::Validations [JV]
18
-
19
- Model.validators
20
- Model.validators_on(:field)
21
-
22
- * #to_key was added to ActiveModel::Lint so we can generate DOM IDs for
23
- AMo objects with composite keys [MG]
24
-
25
-
26
- *Rails 3.0.0 [beta 1] (February 4, 2010)*
27
-
28
- * ActiveModel::Observer#add_observer!
29
-
30
- It has a custom hook to define after_find that should really be in a
31
- ActiveRecord::Observer subclass:
32
-
33
- def add_observer!(klass)
34
- klass.add_observer(self)
35
- klass.class_eval 'def after_find() end' unless
36
- klass.respond_to?(:after_find)
37
- end
38
-
39
- * Change the ActiveModel::Base.include_root_in_json default to true for Rails 3 [DHH]
1
+ *Edge*
40
2
 
41
3
  * Add validates_format_of :without => /regexp/ option. #430 [Elliot Winkler, Peer Allan]
42
4
 
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2010 David Heinemeier Hansson
1
+ Copyright (c) 2004-2009 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README CHANGED
@@ -1,205 +1,21 @@
1
- = Active Model - defined interfaces for Rails
2
-
3
- Prior to Rails 3.0, if a plugin or gem developer wanted to be able to have
4
- an object interact with Action Pack helpers, it was required to either
5
- copy chunks of code from Rails, or monkey patch entire helpers to make them
6
- handle objects that did not look like Active Record. This generated code
7
- duplication and fragile applications that broke on upgrades.
8
-
9
- Active Model is a solution for this problem.
10
-
11
- Active Model provides a known set of interfaces that your objects can implement
12
- to then present a common interface to the Action Pack helpers. You can include
13
- functionality from the following modules:
1
+ Active Model
2
+ ==============
14
3
 
15
- * Adding attribute magic to your objects
4
+ Totally experimental library that aims to extract common model mixins from
5
+ ActiveRecord for use in ActiveResource (and other similar libraries).
6
+ This is in a very rough state (no autotest or spec rake tasks set up yet),
7
+ so please excuse the mess.
16
8
 
17
- Add prefixes and suffixes to defined attribute methods...
18
-
19
- class Person
20
- include ActiveModel::AttributeMethods
21
-
22
- attribute_method_prefix 'clear_'
23
- define_attribute_methods [:name, :age]
24
-
25
- attr_accessor :name, :age
26
-
27
- def clear_attribute(attr)
28
- send("#{attr}=", nil)
29
- end
30
- end
31
-
32
- ...gives you clear_name, clear_age.
33
-
34
- {Learn more}[link:classes/ActiveModel/AttributeMethods.html]
35
-
36
- * Adding callbacks to your objects
9
+ Here's what I plan to extract:
10
+ * ActiveModel::Observing
11
+ * ActiveModel::Callbacks
12
+ * ActiveModel::Validations
37
13
 
38
- class Person
39
- extend ActiveModel::Callbacks
40
- define_model_callbacks :create
41
-
42
- def create
43
- _run_create_callbacks do
44
- # Your create action methods here
45
- end
46
- end
47
- end
48
-
49
- ...gives you before_create, around_create and after_create class methods that
50
- wrap your create method.
51
-
52
- {Learn more}[link:classes/ActiveModel/CallBacks.html]
14
+ # for ActiveResource params and ActiveRecord options
15
+ * ActiveModel::Scoping
53
16
 
54
- * For classes that already look like an Active Record object
17
+ # to_json, to_xml, etc
18
+ * ActiveModel::Serialization
55
19
 
56
- class Person
57
- include ActiveModel::Conversion
58
- end
59
-
60
- ...returns the class itself when sent :to_model
61
-
62
- {Learn more}[link:classes/ActiveModel/Conversion.html]
63
-
64
- * Tracking changes in your object
65
-
66
- Provides all the value tracking features implemented by ActiveRecord...
67
-
68
- person = Person.new
69
- person.name # => nil
70
- person.changed? # => false
71
- person.name = 'bob'
72
- person.changed? # => true
73
- person.changed # => ['name']
74
- person.changes # => { 'name' => [nil, 'bob'] }
75
- person.name = 'robert'
76
- person.save
77
- person.previous_changes # => {'name' => ['bob, 'robert']}
78
-
79
- {Learn more}[link:classes/ActiveModel/Dirty.html]
80
-
81
- * Adding +errors+ support to your object
82
-
83
- Provides the error messages to allow your object to interact with Action Pack
84
- helpers seamlessly...
85
-
86
- class Person
87
-
88
- def initialize
89
- @errors = ActiveModel::Errors.new(self)
90
- end
91
-
92
- attr_accessor :name
93
- attr_reader :errors
94
-
95
- def validate!
96
- errors.add(:name, "can not be nil") if name == nil
97
- end
98
-
99
- def ErrorsPerson.human_attribute_name(attr, options = {})
100
- "Name"
101
- end
102
-
103
- end
104
-
105
- ... gives you...
106
-
107
- person.errors.full_messages
108
- # => ["Name Can not be nil"]
109
- person.errors.full_messages
110
- # => ["Name Can not be nil"]
111
-
112
- {Learn more}[link:classes/ActiveModel/Errors.html]
113
-
114
- * Testing the compliance of your object
115
-
116
- Use ActiveModel::Lint to test the compliance of your object to the
117
- basic ActiveModel API...
118
-
119
- {Learn more}[link:classes/ActiveModel/Lint/Tests.html]
120
-
121
- * Providing a human face to your object
122
-
123
- ActiveModel::Naming provides your model with the model_name convention
124
- and a human_name attribute...
125
-
126
- class NamedPerson
127
- extend ActiveModel::Naming
128
- end
129
-
130
- ...gives you...
131
-
132
- NamedPerson.model_name #=> "NamedPerson"
133
- NamedPerson.model_name.human #=> "Named person"
134
-
135
- {Learn more}[link:classes/ActiveModel/Naming.html]
136
-
137
- * Adding observer support to your objects
138
-
139
- ActiveModel::Observers allows your object to implement the Observer
140
- pattern in a Rails App and take advantage of all the standard observer
141
- functions.
142
-
143
- {Learn more}[link:classes/ActiveModel/Observer.html]
144
-
145
- * Making your object serializable
146
-
147
- ActiveModel::Serialization provides a standard interface for your object
148
- to provide to_json or to_xml serialization...
149
-
150
- s = SerialPerson.new
151
- s.serializable_hash # => {"name"=>nil}
152
- s.to_json # => "{\"name\":null}"
153
- s.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
154
-
155
- {Learn more}[link:classes/ActiveModel/Serialization.html]
156
-
157
- * Integrating with Rail's internationalization (i18n) handling through
158
- ActiveModel::Translations...
159
-
160
- class Person
161
- extend ActiveModel::Translation
162
- end
163
-
164
- {Learn more}[link:classes/ActiveModel/Translation.html]
165
-
166
- * Providing a full Validation stack for your objects...
167
-
168
- class Person
169
- include ActiveModel::Validations
170
-
171
- attr_accessor :first_name, :last_name
172
-
173
-
174
- validates_each :first_name, :last_name do |record, attr, value|
175
- record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
176
- end
177
- end
178
-
179
-
180
- person = Person.new(:first_name => 'zoolander')
181
- person.valid? #=> false
182
-
183
- {Learn more}[link:classes/ActiveModel/Validations.html]
184
-
185
- * Make custom validators
186
-
187
- class Person
188
- include ActiveModel::Validations
189
- validates_with HasNameValidator
190
- attr_accessor :name
191
- end
192
-
193
- class HasNameValidator < ActiveModel::Validator
194
- def validate(record)
195
- record.errors[:name] = "must exist" if record.name.blank?
196
- end
197
- end
198
-
199
- p = ValidatorPerson.new
200
- p.valid? #=> false
201
- p.errors.full_messages #=> ["Name must exist"]
202
- p.name = "Bob"
203
- p.valid? #=> true
204
-
205
- {Learn more}[link:classes/ActiveModel/Validator.html]
20
+ I'm trying to keep ActiveRecord compatibility where possible, but I'm
21
+ annotating the spots where I'm diverging a bit.
data/lib/active_model.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2004-2010 David Heinemeier Hansson
2
+ # Copyright (c) 2004-2009 David Heinemeier Hansson
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -21,41 +21,32 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
25
- $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
24
+ activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
25
+ $:.unshift(activesupport_path) if File.directory?(activesupport_path)
26
26
  require 'active_support'
27
27
 
28
-
29
28
  module ActiveModel
30
- extend ActiveSupport::Autoload
31
-
32
- autoload :AttributeMethods
33
- autoload :BlockValidator, 'active_model/validator'
34
- autoload :Callbacks
35
- autoload :Conversion
36
- autoload :DeprecatedErrorMethods
37
- autoload :Dirty
38
- autoload :EachValidator, 'active_model/validator'
39
- autoload :Errors
40
- autoload :Lint
29
+ autoload :AttributeMethods, 'active_model/attribute_methods'
30
+ autoload :Conversion, 'active_model/conversion'
31
+ autoload :DeprecatedErrorMethods, 'active_model/deprecated_error_methods'
32
+ autoload :Dirty, 'active_model/dirty'
33
+ autoload :Errors, 'active_model/errors'
34
+ autoload :Lint, 'active_model/lint'
41
35
  autoload :Name, 'active_model/naming'
42
- autoload :Naming
36
+ autoload :Naming, 'active_model/naming'
43
37
  autoload :Observer, 'active_model/observing'
44
- autoload :Observing
45
- autoload :Serialization
46
- autoload :TestCase
47
- autoload :Translation
48
- autoload :VERSION
49
- autoload :Validations
50
- autoload :Validator
38
+ autoload :Observing, 'active_model/observing'
39
+ autoload :Serialization, 'active_model/serialization'
40
+ autoload :StateMachine, 'active_model/state_machine'
41
+ autoload :TestCase, 'active_model/test_case'
42
+ autoload :Validations, 'active_model/validations'
43
+ autoload :ValidationsRepairHelper, 'active_model/validations_repair_helper'
44
+ autoload :VERSION, 'active_model/version'
51
45
 
52
46
  module Serializers
53
- extend ActiveSupport::Autoload
54
-
55
- autoload :JSON
56
- autoload :Xml
47
+ autoload :JSON, 'active_model/serializers/json'
48
+ autoload :Xml, 'active_model/serializers/xml'
57
49
  end
58
50
  end
59
51
 
60
- require 'active_support/i18n'
61
52
  I18n.load_path << File.dirname(__FILE__) + '/active_model/locale/en.yml'
@@ -5,54 +5,10 @@ module ActiveModel
5
5
  class MissingAttributeError < NoMethodError
6
6
  end
7
7
 
8
- # <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and suffixes
9
- # to your methods as well as handling the creation of Active Record like class methods
10
- # such as +table_name+.
11
- #
12
- # The requirements to implement ActiveModel::AttributeMethods are:
13
- #
14
- # * <tt>include ActiveModel::AttributeMethods</tt> in your object
15
- # * Call each Attribute Method module method you want to add, such as
16
- # attribute_method_suffix or attribute_method_prefix
17
- # * Call <tt>define_attribute_methods</tt> after the other methods are
18
- # called.
19
- # * Define the various generic +_attribute+ methods that you have declared
20
- #
21
- # A minimal implementation could be:
22
- #
23
- # class Person
24
- # include ActiveModel::AttributeMethods
25
- #
26
- # attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
27
- # attribute_method_suffix '_contrived?'
28
- # attribute_method_prefix 'clear_'
29
- # define_attribute_methods ['name']
30
- #
31
- # attr_accessor :name
32
- #
33
- # private
34
- #
35
- # def attribute_contrived?(attr)
36
- # true
37
- # end
38
- #
39
- # def clear_attribute(attr)
40
- # send("#{attr}=", nil)
41
- # end
42
- #
43
- # def reset_attribute_to_default!(attr)
44
- # send("#{attr}=", "Default Name")
45
- # end
46
- # end
47
- #
48
- # Please notice that whenever you include ActiveModel::AtributeMethods in your class,
49
- # it requires you to implement a <tt>attributes</tt> methods which returns a hash with
50
- # each attribute name in your model as hash key and the attribute value as hash value.
51
- # Hash keys must be a string.
52
- #
53
8
  module AttributeMethods
54
9
  extend ActiveSupport::Concern
55
10
 
11
+ # Declare and check for suffixed attribute methods.
56
12
  module ClassMethods
57
13
  # Defines an "attribute" method (like +inheritance_column+ or
58
14
  # +table_name+). A new (class) method will be created with the
@@ -66,43 +22,21 @@ module ActiveModel
66
22
  #
67
23
  # Example:
68
24
  #
69
- # class Person
70
- #
71
- # include ActiveModel::AttributeMethods
72
- #
73
- # cattr_accessor :primary_key
74
- # cattr_accessor :inheritance_column
75
- #
25
+ # class A < ActiveRecord::Base
76
26
  # define_attr_method :primary_key, "sysid"
77
27
  # define_attr_method( :inheritance_column ) do
78
28
  # original_inheritance_column + "_id"
79
29
  # end
80
- #
81
30
  # end
82
- #
83
- # Provides you with:
84
- #
85
- # AttributePerson.primary_key
86
- # # => "sysid"
87
- # AttributePerson.inheritance_column = 'address'
88
- # AttributePerson.inheritance_column
89
- # # => 'address_id'
90
31
  def define_attr_method(name, value=nil, &block)
91
- sing = singleton_class
92
- sing.class_eval <<-eorb, __FILE__, __LINE__ + 1
93
- if method_defined?(:original_#{name})
94
- undef :original_#{name}
95
- end
96
- alias_method :original_#{name}, :#{name}
97
- eorb
32
+ sing = metaclass
33
+ sing.send :alias_method, "original_#{name}", name
98
34
  if block_given?
99
35
  sing.send :define_method, name, &block
100
36
  else
101
37
  # use eval instead of a block to work around a memory leak in dev
102
38
  # mode in fcgi
103
- sing.class_eval <<-eorb, __FILE__, __LINE__ + 1
104
- def #{name}; #{value.to_s.inspect}; end
105
- eorb
39
+ sing.class_eval "def #{name}; #{value.to_s.inspect}; end"
106
40
  end
107
41
  end
108
42
 
@@ -120,25 +54,19 @@ module ActiveModel
120
54
  #
121
55
  # For example:
122
56
  #
123
- # class Person
124
- #
125
- # include ActiveModel::AttributeMethods
126
- # attr_accessor :name
57
+ # class Person < ActiveRecord::Base
127
58
  # attribute_method_prefix 'clear_'
128
- # define_attribute_methods [:name]
129
59
  #
130
60
  # private
131
- #
132
- # def clear_attribute(attr)
133
- # send("#{attr}=", nil)
134
- # end
61
+ # def clear_attribute(attr)
62
+ # ...
63
+ # end
135
64
  # end
136
65
  #
137
- # person = Person.new
138
- # person.name = "Bob"
139
- # person.name # => "Bob"
66
+ # person = Person.find(1)
67
+ # person.name # => 'Gem'
140
68
  # person.clear_name
141
- # person.name # => nil
69
+ # person.name # => ''
142
70
  def attribute_method_prefix(*prefixes)
143
71
  attribute_method_matchers.concat(prefixes.map { |prefix| AttributeMethodMatcher.new :prefix => prefix })
144
72
  undefine_attribute_methods
@@ -158,24 +86,18 @@ module ActiveModel
158
86
  #
159
87
  # For example:
160
88
  #
161
- # class Person
162
- #
163
- # include ActiveModel::AttributeMethods
164
- # attr_accessor :name
89
+ # class Person < ActiveRecord::Base
165
90
  # attribute_method_suffix '_short?'
166
- # define_attribute_methods [:name]
167
91
  #
168
92
  # private
169
- #
170
- # def attribute_short?(attr)
171
- # send(attr).length < 5
172
- # end
93
+ # def attribute_short?(attr)
94
+ # ...
95
+ # end
173
96
  # end
174
97
  #
175
- # person = Person.new
176
- # person.name = "Bob"
177
- # person.name # => "Bob"
178
- # person.name_short? # => true
98
+ # person = Person.find(1)
99
+ # person.name # => 'Gem'
100
+ # person.name_short? # => true
179
101
  def attribute_method_suffix(*suffixes)
180
102
  attribute_method_matchers.concat(suffixes.map { |suffix| AttributeMethodMatcher.new :suffix => suffix })
181
103
  undefine_attribute_methods
@@ -196,21 +118,16 @@ module ActiveModel
196
118
  #
197
119
  # For example:
198
120
  #
199
- # class Person
200
- #
201
- # include ActiveModel::AttributeMethods
202
- # attr_accessor :name
121
+ # class Person < ActiveRecord::Base
203
122
  # attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
204
- # define_attribute_methods [:name]
205
123
  #
206
124
  # private
207
- #
208
- # def reset_attribute_to_default!(attr)
209
- # ...
210
- # end
125
+ # def reset_attribute_to_default!(attr)
126
+ # ...
127
+ # end
211
128
  # end
212
129
  #
213
- # person = Person.new
130
+ # person = Person.find(1)
214
131
  # person.name # => 'Gem'
215
132
  # person.reset_name_to_default!
216
133
  # person.name # => 'Gemma'
@@ -221,7 +138,7 @@ module ActiveModel
221
138
 
222
139
  def alias_attribute(new_name, old_name)
223
140
  attribute_method_matchers.each do |matcher|
224
- module_eval <<-STR, __FILE__, __LINE__ + 1
141
+ module_eval <<-STR, __FILE__, __LINE__+1
225
142
  def #{matcher.method_name(new_name)}(*args)
226
143
  send(:#{matcher.method_name(old_name)}, *args)
227
144
  end
@@ -229,30 +146,6 @@ module ActiveModel
229
146
  end
230
147
  end
231
148
 
232
- # Declares a the attributes that should be prefixed and suffixed by
233
- # ActiveModel::AttributeMethods.
234
- #
235
- # To use, pass in an array of attribute names (as strings or symbols),
236
- # be sure to declare +define_attribute_methods+ after you define any
237
- # prefix, suffix or affix methods, or they will not hook in.
238
- #
239
- # class Person
240
- #
241
- # include ActiveModel::AttributeMethods
242
- # attr_accessor :name, :age, :address
243
- # attribute_method_prefix 'clear_'
244
- #
245
- # # Call to define_attribute_methods must appear after the
246
- # # attribute_method_prefix, attribute_method_suffix or
247
- # # attribute_method_affix declares.
248
- # define_attribute_methods [:name, :age, :address]
249
- #
250
- # private
251
- #
252
- # def clear_attribute(attr)
253
- # ...
254
- # end
255
- # end
256
149
  def define_attribute_methods(attr_names)
257
150
  return if attribute_methods_generated?
258
151
  attr_names.each do |attr_name|
@@ -263,13 +156,8 @@ module ActiveModel
263
156
  if respond_to?(generate_method)
264
157
  send(generate_method, attr_name)
265
158
  else
266
- method_name = matcher.method_name(attr_name)
267
-
268
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
269
- if method_defined?(:#{method_name})
270
- undef :#{method_name}
271
- end
272
- def #{method_name}(*args)
159
+ generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__+1
160
+ def #{matcher.method_name(attr_name)}(*args)
273
161
  send(:#{matcher.method_missing_target}, '#{attr_name}', *args)
274
162
  end
275
163
  STR
@@ -280,7 +168,6 @@ module ActiveModel
280
168
  @attribute_methods_generated = true
281
169
  end
282
170
 
283
- # Removes all the preiously dynamically defined methods from the class
284
171
  def undefine_attribute_methods
285
172
  generated_attribute_methods.module_eval do
286
173
  instance_methods.each { |m| undef_method(m) }
@@ -288,7 +175,6 @@ module ActiveModel
288
175
  @attribute_methods_generated = nil
289
176
  end
290
177
 
291
- # Returns true if the attribute methods defined have been generated.
292
178
  def generated_attribute_methods #:nodoc:
293
179
  @generated_attribute_methods ||= begin
294
180
  mod = Module.new
@@ -297,7 +183,6 @@ module ActiveModel
297
183
  end
298
184
  end
299
185
 
300
- # Returns true if the attribute methods defined have been generated.
301
186
  def attribute_methods_generated?
302
187
  @attribute_methods_generated ||= nil
303
188
  end