activemodel 3.0.0.rc → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ *Rails 3.0.0 [release candidate 2] (August 23rd, 2010)*
2
+
3
+ * No material changes (see http://github.com/rails/rails/compare/v3.0.0_RC...v3.0.0_RC2 for gory details)
4
+
5
+
1
6
  *Rails 3.0.0 [release candidate] (July 26th, 2010)*
2
7
 
3
8
  * Added ActiveModel::MassAssignmentSecurity [Eric Chapweske, Josh Kalderimis]
@@ -16,7 +21,7 @@
16
21
  *Rails 3.0.0 [beta 2] (April 1st, 2010)*
17
22
 
18
23
  * #new_record? and #destroyed? were removed from ActiveModel::Lint. Use
19
- persisted? instead. A model is persisted if it's not a new_record? and it was
24
+ persisted? instead. A model is persisted if it's not a new_record? and it was
20
25
  not destroyed? [MG]
21
26
 
22
27
  * Added validations reflection in ActiveModel::Validations [JV]
@@ -18,38 +18,38 @@ modules:
18
18
 
19
19
  class Person
20
20
  include ActiveModel::AttributeMethods
21
-
21
+
22
22
  attribute_method_prefix 'clear_'
23
23
  define_attribute_methods [:name, :age]
24
-
24
+
25
25
  attr_accessor :name, :age
26
-
26
+
27
27
  def clear_attribute(attr)
28
28
  send("#{attr}=", nil)
29
29
  end
30
30
  end
31
-
31
+
32
32
  person.clear_name
33
33
  person.clear_age
34
-
34
+
35
35
  {Learn more}[link:classes/ActiveModel/AttributeMethods.html]
36
-
36
+
37
37
  * Callbacks for certain operations
38
38
 
39
39
  class Person
40
40
  extend ActiveModel::Callbacks
41
41
  define_model_callbacks :create
42
-
42
+
43
43
  def create
44
44
  _run_create_callbacks do
45
45
  # Your create action methods here
46
46
  end
47
47
  end
48
48
  end
49
-
49
+
50
50
  This generates +before_create+, +around_create+ and +after_create+
51
51
  class methods that wrap your create method.
52
-
52
+
53
53
  {Learn more}[link:classes/ActiveModel/CallBacks.html]
54
54
 
55
55
  * Tracking value changes
@@ -66,36 +66,36 @@ modules:
66
66
  person.name = 'robert'
67
67
  person.save
68
68
  person.previous_changes # => {'name' => ['bob, 'robert']}
69
-
69
+
70
70
  {Learn more}[link:classes/ActiveModel/Dirty.html]
71
71
 
72
72
  * Adding +errors+ interface to objects
73
73
 
74
74
  Exposing error messages allows objects to interact with Action Pack
75
75
  helpers seamlessly.
76
-
76
+
77
77
  class Person
78
-
78
+
79
79
  def initialize
80
80
  @errors = ActiveModel::Errors.new(self)
81
81
  end
82
-
82
+
83
83
  attr_accessor :name
84
84
  attr_reader :errors
85
-
85
+
86
86
  def validate!
87
87
  errors.add(:name, "can not be nil") if name == nil
88
88
  end
89
-
89
+
90
90
  def ErrorsPerson.human_attribute_name(attr, options = {})
91
91
  "Name"
92
92
  end
93
-
93
+
94
94
  end
95
-
95
+
96
96
  person.errors.full_messages
97
97
  # => ["Name Can not be nil"]
98
-
98
+
99
99
  person.errors.full_messages
100
100
  # => ["Name Can not be nil"]
101
101
 
@@ -106,9 +106,9 @@ modules:
106
106
  class NamedPerson
107
107
  extend ActiveModel::Naming
108
108
  end
109
-
110
- NamedPerson.model_name #=> "NamedPerson"
111
- NamedPerson.model_name.human #=> "Named person"
109
+
110
+ NamedPerson.model_name # => "NamedPerson"
111
+ NamedPerson.model_name.human # => "Named person"
112
112
 
113
113
  {Learn more}[link:classes/ActiveModel/Naming.html]
114
114
 
@@ -117,19 +117,19 @@ modules:
117
117
  ActiveModel::Observers allows your object to implement the Observer
118
118
  pattern in a Rails App and take advantage of all the standard observer
119
119
  functions.
120
-
120
+
121
121
  {Learn more}[link:classes/ActiveModel/Observer.html]
122
122
 
123
123
  * Making objects serializable
124
124
 
125
125
  ActiveModel::Serialization provides a standard interface for your object
126
126
  to provide +to_json+ or +to_xml+ serialization.
127
-
127
+
128
128
  s = SerialPerson.new
129
129
  s.serializable_hash # => {"name"=>nil}
130
130
  s.to_json # => "{\"name\":null}"
131
131
  s.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
132
-
132
+
133
133
  {Learn more}[link:classes/ActiveModel/Serialization.html]
134
134
 
135
135
  * Internationalization (i18n) support
@@ -137,10 +137,10 @@ modules:
137
137
  class Person
138
138
  extend ActiveModel::Translation
139
139
  end
140
-
140
+
141
141
  Person.human_attribute_name('my_attribute')
142
- #=> "My attribute"
143
-
142
+ # => "My attribute"
143
+
144
144
  {Learn more}[link:classes/ActiveModel/Translation.html]
145
145
 
146
146
  * Validation support
@@ -157,10 +157,10 @@ modules:
157
157
 
158
158
  person = Person.new
159
159
  person.first_name = 'zoolander'
160
- person.valid? #=> false
160
+ person.valid? # => false
161
161
 
162
162
  {Learn more}[link:classes/ActiveModel/Validations.html]
163
-
163
+
164
164
  * Custom validators
165
165
 
166
166
  class Person
@@ -168,17 +168,17 @@ modules:
168
168
  validates_with HasNameValidator
169
169
  attr_accessor :name
170
170
  end
171
-
171
+
172
172
  class HasNameValidator < ActiveModel::Validator
173
173
  def validate(record)
174
174
  record.errors[:name] = "must exist" if record.name.blank?
175
175
  end
176
176
  end
177
-
177
+
178
178
  p = ValidatorPerson.new
179
- p.valid? #=> false
180
- p.errors.full_messages #=> ["Name must exist"]
179
+ p.valid? # => false
180
+ p.errors.full_messages # => ["Name must exist"]
181
181
  p.name = "Bob"
182
- p.valid? #=> true
182
+ p.valid? # => true
183
183
 
184
184
  {Learn more}[link:classes/ActiveModel/Validator.html]
@@ -9,46 +9,46 @@ module ActiveModel
9
9
  # <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and suffixes
10
10
  # to your methods as well as handling the creation of Active Record like class methods
11
11
  # such as +table_name+.
12
- #
12
+ #
13
13
  # The requirements to implement ActiveModel::AttributeMethods are to:
14
14
  #
15
15
  # * <tt>include ActiveModel::AttributeMethods</tt> in your object
16
- # * Call each Attribute Method module method you want to add, such as
16
+ # * Call each Attribute Method module method you want to add, such as
17
17
  # attribute_method_suffix or attribute_method_prefix
18
18
  # * Call <tt>define_attribute_methods</tt> after the other methods are
19
19
  # called.
20
20
  # * Define the various generic +_attribute+ methods that you have declared
21
- #
21
+ #
22
22
  # A minimal implementation could be:
23
- #
23
+ #
24
24
  # class Person
25
25
  # include ActiveModel::AttributeMethods
26
- #
26
+ #
27
27
  # attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
28
28
  # attribute_method_suffix '_contrived?'
29
29
  # attribute_method_prefix 'clear_'
30
30
  # define_attribute_methods ['name']
31
- #
31
+ #
32
32
  # attr_accessor :name
33
- #
33
+ #
34
34
  # private
35
- #
35
+ #
36
36
  # def attribute_contrived?(attr)
37
37
  # true
38
38
  # end
39
- #
39
+ #
40
40
  # def clear_attribute(attr)
41
41
  # send("#{attr}=", nil)
42
42
  # end
43
- #
43
+ #
44
44
  # def reset_attribute_to_default!(attr)
45
45
  # send("#{attr}=", "Default Name")
46
46
  # end
47
47
  # end
48
48
  #
49
49
  # Notice that whenever you include ActiveModel::AttributeMethods in your class,
50
- # it requires you to implement a <tt>attributes</tt> methods which returns a hash
51
- # with each attribute name in your model as hash key and the attribute value as
50
+ # it requires you to implement a <tt>attributes</tt> methods which returns a hash
51
+ # with each attribute name in your model as hash key and the attribute value as
52
52
  # hash value.
53
53
  #
54
54
  # Hash keys must be strings.
@@ -57,34 +57,34 @@ module ActiveModel
57
57
  extend ActiveSupport::Concern
58
58
 
59
59
  module ClassMethods
60
- # Defines an "attribute" method (like +inheritance_column+ or +table_name+).
61
- # A new (class) method will be created with the given name. If a value is
62
- # specified, the new method will return that value (as a string).
63
- # Otherwise, the given block will be used to compute the value of the
60
+ # Defines an "attribute" method (like +inheritance_column+ or +table_name+).
61
+ # A new (class) method will be created with the given name. If a value is
62
+ # specified, the new method will return that value (as a string).
63
+ # Otherwise, the given block will be used to compute the value of the
64
64
  # method.
65
65
  #
66
66
  # The original method will be aliased, with the new name being prefixed
67
- # with "original_". This allows the new method to access the original
67
+ # with "original_". This allows the new method to access the original
68
68
  # value.
69
69
  #
70
70
  # Example:
71
71
  #
72
72
  # class Person
73
- #
73
+ #
74
74
  # include ActiveModel::AttributeMethods
75
- #
75
+ #
76
76
  # cattr_accessor :primary_key
77
77
  # cattr_accessor :inheritance_column
78
- #
78
+ #
79
79
  # define_attr_method :primary_key, "sysid"
80
80
  # define_attr_method( :inheritance_column ) do
81
81
  # original_inheritance_column + "_id"
82
82
  # end
83
- #
83
+ #
84
84
  # end
85
- #
85
+ #
86
86
  # Provides you with:
87
- #
87
+ #
88
88
  # AttributePerson.primary_key
89
89
  # # => "sysid"
90
90
  # AttributePerson.inheritance_column = 'address'
@@ -118,20 +118,20 @@ module ActiveModel
118
118
  #
119
119
  # #{prefix}attribute(#{attr}, *args, &block)
120
120
  #
121
- # An instance method <tt>#{prefix}attribute</tt> must exist and accept
121
+ # An instance method <tt>#{prefix}attribute</tt> must exist and accept
122
122
  # at least the +attr+ argument.
123
123
  #
124
124
  # For example:
125
125
  #
126
126
  # class Person
127
- #
127
+ #
128
128
  # include ActiveModel::AttributeMethods
129
129
  # attr_accessor :name
130
130
  # attribute_method_prefix 'clear_'
131
131
  # define_attribute_methods [:name]
132
132
  #
133
133
  # private
134
- #
134
+ #
135
135
  # def clear_attribute(attr)
136
136
  # send("#{attr}=", nil)
137
137
  # end
@@ -162,14 +162,14 @@ module ActiveModel
162
162
  # For example:
163
163
  #
164
164
  # class Person
165
- #
165
+ #
166
166
  # include ActiveModel::AttributeMethods
167
167
  # attr_accessor :name
168
168
  # attribute_method_suffix '_short?'
169
169
  # define_attribute_methods [:name]
170
170
  #
171
171
  # private
172
- #
172
+ #
173
173
  # def attribute_short?(attr)
174
174
  # send(attr).length < 5
175
175
  # end
@@ -200,14 +200,14 @@ module ActiveModel
200
200
  # For example:
201
201
  #
202
202
  # class Person
203
- #
203
+ #
204
204
  # include ActiveModel::AttributeMethods
205
205
  # attr_accessor :name
206
206
  # attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
207
207
  # define_attribute_methods [:name]
208
208
  #
209
209
  # private
210
- #
210
+ #
211
211
  # def reset_attribute_to_default!(attr)
212
212
  # ...
213
213
  # end
@@ -232,15 +232,15 @@ module ActiveModel
232
232
  end
233
233
  end
234
234
 
235
- # Declares a the attributes that should be prefixed and suffixed by
235
+ # Declares a the attributes that should be prefixed and suffixed by
236
236
  # ActiveModel::AttributeMethods.
237
- #
237
+ #
238
238
  # To use, pass in an array of attribute names (as strings or symbols),
239
239
  # be sure to declare +define_attribute_methods+ after you define any
240
240
  # prefix, suffix or affix methods, or they will not hook in.
241
- #
241
+ #
242
242
  # class Person
243
- #
243
+ #
244
244
  # include ActiveModel::AttributeMethods
245
245
  # attr_accessor :name, :age, :address
246
246
  # attribute_method_prefix 'clear_'
@@ -251,7 +251,7 @@ module ActiveModel
251
251
  # define_attribute_methods [:name, :age, :address]
252
252
  #
253
253
  # private
254
- #
254
+ #
255
255
  # def clear_attribute(attr)
256
256
  # ...
257
257
  # end
@@ -283,7 +283,7 @@ module ActiveModel
283
283
  @attribute_methods_generated = true
284
284
  end
285
285
 
286
- # Removes all the preiously dynamically defined methods from the class
286
+ # Removes all the previously dynamically defined methods from the class
287
287
  def undefine_attribute_methods
288
288
  generated_attribute_methods.module_eval do
289
289
  instance_methods.each { |m| undef_method(m) }
@@ -344,16 +344,16 @@ module ActiveModel
344
344
  end
345
345
  end
346
346
 
347
- # Allows access to the object attributes, which are held in the
348
- # <tt>@attributes</tt> hash, as though they were first-class methods. So a
349
- # Person class with a name attribute can use Person#name and Person#name=
347
+ # Allows access to the object attributes, which are held in the
348
+ # <tt>@attributes</tt> hash, as though they were first-class methods. So a
349
+ # Person class with a name attribute can use Person#name and Person#name=
350
350
  # and never directly use the attributes hash -- except for multiple assigns
351
- # with ActiveRecord#attributes=. A Milestone class can also ask
352
- # Milestone#completed? to test that the completed attribute is not +nil+
351
+ # with ActiveRecord#attributes=. A Milestone class can also ask
352
+ # Milestone#completed? to test that the completed attribute is not +nil+
353
353
  # or 0.
354
354
  #
355
- # It's also possible to instantiate related objects, so a Client class
356
- # belonging to the clients table with a +master_id+ foreign key can
355
+ # It's also possible to instantiate related objects, so a Client class
356
+ # belonging to the clients table with a +master_id+ foreign key can
357
357
  # instantiate master through Client#master.
358
358
  def method_missing(method_id, *args, &block)
359
359
  method_name = method_id.to_s
@@ -3,49 +3,49 @@ require 'active_support/callbacks'
3
3
 
4
4
  module ActiveModel
5
5
  # == Active Model Callbacks
6
- #
6
+ #
7
7
  # Provides an interface for any class to have Active Record like callbacks.
8
- #
8
+ #
9
9
  # Like the Active Record methods, the callback chain is aborted as soon as
10
10
  # one of the methods in the chain returns false.
11
11
  #
12
12
  # First, extend ActiveModel::Callbacks from the class you are creating:
13
- #
13
+ #
14
14
  # class MyModel
15
15
  # extend ActiveModel::Callbacks
16
16
  # end
17
- #
17
+ #
18
18
  # Then define a list of methods that you want callbacks attached to:
19
- #
19
+ #
20
20
  # define_model_callbacks :create, :update
21
- #
21
+ #
22
22
  # This will provide all three standard callbacks (before, around and after) for
23
- # both the :create and :update methods. To implement, you need to wrap the methods
23
+ # both the :create and :update methods. To implement, you need to wrap the methods
24
24
  # you want callbacks on in a block so that the callbacks get a chance to fire:
25
- #
25
+ #
26
26
  # def create
27
27
  # _run_create_callbacks do
28
28
  # # Your create action methods here
29
29
  # end
30
30
  # end
31
- #
31
+ #
32
32
  # The _run_<method_name>_callbacks methods are dynamically created when you extend
33
33
  # the <tt>ActiveModel::Callbacks</tt> module.
34
- #
34
+ #
35
35
  # Then in your class, you can use the +before_create+, +after_create+ and +around_create+
36
36
  # methods, just as you would in an Active Record module.
37
- #
37
+ #
38
38
  # before_create :action_before_create
39
- #
39
+ #
40
40
  # def action_before_create
41
41
  # # Your code here
42
42
  # end
43
- #
44
- # You can choose not to have all three callbacks by passing a hash to the
43
+ #
44
+ # You can choose not to have all three callbacks by passing a hash to the
45
45
  # define_model_callbacks method.
46
- #
46
+ #
47
47
  # define_model_callbacks :create, :only => :after, :before
48
- #
48
+ #
49
49
  # Would only create the after_create and before_create callback methods in your
50
50
  # class.
51
51
  module Callbacks
@@ -56,44 +56,47 @@ module ActiveModel
56
56
  end
57
57
 
58
58
  # define_model_callbacks accepts the same options define_callbacks does, in case
59
- # you want to overwrite a default. Besides that, it also accepts an :only option,
59
+ # you want to overwrite a default. Besides that, it also accepts an :only option,
60
60
  # where you can choose if you want all types (before, around or after) or just some.
61
61
  #
62
62
  # define_model_callbacks :initializer, :only => :after
63
- #
63
+ #
64
64
  # Note, the <tt>:only => <type></tt> hash will apply to all callbacks defined on
65
65
  # that method call. To get around this you can call the define_model_callbacks
66
66
  # method as many times as you need.
67
- #
67
+ #
68
68
  # define_model_callbacks :create, :only => :after
69
69
  # define_model_callbacks :update, :only => :before
70
70
  # define_model_callbacks :destroy, :only => :around
71
- #
71
+ #
72
72
  # Would create +after_create+, +before_update+ and +around_destroy+ methods only.
73
- #
73
+ #
74
74
  # You can pass in a class to before_<type>, after_<type> and around_<type>, in which
75
75
  # case the callback will call that class's <action>_<type> method passing the object
76
76
  # that the callback is being called on.
77
- #
77
+ #
78
78
  # class MyModel
79
79
  # extend ActiveModel::Callbacks
80
80
  # define_model_callbacks :create
81
- #
81
+ #
82
82
  # before_create AnotherClass
83
83
  # end
84
- #
84
+ #
85
85
  # class AnotherClass
86
86
  # def self.before_create( obj )
87
87
  # # obj is the MyModel instance that the callback is being called on
88
88
  # end
89
89
  # end
90
- #
90
+ #
91
91
  def define_model_callbacks(*callbacks)
92
92
  options = callbacks.extract_options!
93
- options = { :terminator => "result == false", :scope => [:kind, :name] }.merge(options)
93
+ options = {
94
+ :terminator => "result == false",
95
+ :scope => [:kind, :name],
96
+ :only => [:before, :around, :after]
97
+ }.merge(options)
94
98
 
95
- types = Array.wrap(options.delete(:only))
96
- types = [:before, :around, :after] if types.empty?
99
+ types = Array.wrap(options.delete(:only))
97
100
 
98
101
  callbacks.each do |callback|
99
102
  define_callbacks(callback, options)