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.
- data/CHANGELOG +1 -39
- data/MIT-LICENSE +1 -1
- data/README +16 -200
- data/lib/active_model.rb +19 -28
- data/lib/active_model/attribute_methods.rb +27 -142
- data/lib/active_model/conversion.rb +1 -37
- data/lib/active_model/dirty.rb +12 -51
- data/lib/active_model/errors.rb +22 -146
- data/lib/active_model/lint.rb +14 -48
- data/lib/active_model/locale/en.yml +23 -26
- data/lib/active_model/naming.rb +5 -41
- data/lib/active_model/observing.rb +16 -35
- data/lib/active_model/serialization.rb +0 -57
- data/lib/active_model/serializers/json.rb +8 -13
- data/lib/active_model/serializers/xml.rb +123 -63
- data/lib/active_model/state_machine.rb +70 -0
- data/lib/active_model/state_machine/event.rb +62 -0
- data/lib/active_model/state_machine/machine.rb +75 -0
- data/lib/active_model/state_machine/state.rb +47 -0
- data/lib/active_model/state_machine/state_transition.rb +40 -0
- data/lib/active_model/test_case.rb +2 -0
- data/lib/active_model/validations.rb +62 -125
- data/lib/active_model/validations/acceptance.rb +18 -23
- data/lib/active_model/validations/confirmation.rb +10 -14
- data/lib/active_model/validations/exclusion.rb +13 -15
- data/lib/active_model/validations/format.rb +24 -26
- data/lib/active_model/validations/inclusion.rb +13 -15
- data/lib/active_model/validations/length.rb +65 -61
- data/lib/active_model/validations/numericality.rb +58 -76
- data/lib/active_model/validations/presence.rb +8 -8
- data/lib/active_model/validations/with.rb +22 -90
- data/lib/active_model/validations_repair_helper.rb +35 -0
- data/lib/active_model/version.rb +2 -3
- metadata +19 -63
- data/lib/active_model/callbacks.rb +0 -134
- data/lib/active_model/railtie.rb +0 -2
- data/lib/active_model/translation.rb +0 -60
- data/lib/active_model/validations/validates.rb +0 -108
- data/lib/active_model/validator.rb +0 -183
data/CHANGELOG
CHANGED
@@ -1,42 +1,4 @@
|
|
1
|
-
*
|
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
data/README
CHANGED
@@ -1,205 +1,21 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
39
|
-
|
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
|
-
|
17
|
+
# to_json, to_xml, etc
|
18
|
+
* ActiveModel::Serialization
|
55
19
|
|
56
|
-
|
57
|
-
|
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-
|
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.
|
25
|
-
$:.unshift(activesupport_path) if File.directory?(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
|
-
|
31
|
-
|
32
|
-
autoload :
|
33
|
-
autoload :
|
34
|
-
autoload :
|
35
|
-
autoload :
|
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 :
|
47
|
-
autoload :
|
48
|
-
autoload :
|
49
|
-
autoload :
|
50
|
-
autoload :
|
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
|
-
|
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
|
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 =
|
92
|
-
sing.
|
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
|
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
|
-
#
|
133
|
-
#
|
134
|
-
# end
|
61
|
+
# def clear_attribute(attr)
|
62
|
+
# ...
|
63
|
+
# end
|
135
64
|
# end
|
136
65
|
#
|
137
|
-
# person = Person.
|
138
|
-
# person.name
|
139
|
-
# person.name # => "Bob"
|
66
|
+
# person = Person.find(1)
|
67
|
+
# person.name # => 'Gem'
|
140
68
|
# person.clear_name
|
141
|
-
# person.name # =>
|
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
|
-
#
|
171
|
-
#
|
172
|
-
# end
|
93
|
+
# def attribute_short?(attr)
|
94
|
+
# ...
|
95
|
+
# end
|
173
96
|
# end
|
174
97
|
#
|
175
|
-
# person = Person.
|
176
|
-
# person.name
|
177
|
-
# person.
|
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
|
-
#
|
209
|
-
#
|
210
|
-
# end
|
125
|
+
# def reset_attribute_to_default!(attr)
|
126
|
+
# ...
|
127
|
+
# end
|
211
128
|
# end
|
212
129
|
#
|
213
|
-
# person = Person.
|
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__
|
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
|
-
|
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
|