activemodel 3.0.0.beta4 → 3.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|