activerecord 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +48 -32
- data/README +0 -14
- data/Rakefile +2 -1
- data/lib/active_record/associations/association_proxy.rb +15 -14
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/base.rb +184 -111
- data/lib/active_record/calculations.rb +2 -4
- data/lib/active_record/fixtures.rb +19 -3
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/validations.rb +37 -4
- data/lib/active_record/version.rb +1 -1
- data/test/aaa_create_tables_test.rb +2 -2
- data/test/associations/join_model_test.rb +6 -0
- data/test/associations_test.rb +8 -1
- data/test/finder_test.rb +9 -1
- data/test/fixtures/author.rb +2 -0
- data/test/fixtures_test.rb +16 -0
- data/test/locking_test.rb +9 -0
- data/test/validations_test.rb +8 -0
- metadata +49 -43
- data/test/associations/ar_joins_test.rb +0 -0
data/CHANGELOG
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
*2.0.2* (December 16th, 2007)
|
2
|
+
|
3
|
+
* Ensure optimistic locking handles nil #lock_version values properly. Closes #10510 [rick]
|
4
|
+
|
5
|
+
* Make the Fixtures Test::Unit enhancements more supporting for double-loaded test cases. Closes #10379 [brynary]
|
6
|
+
|
7
|
+
* Fix that validates_acceptance_of still works for non-existent tables (useful for bootstrapping new databases). Closes #10474 [hasmanyjosh]
|
8
|
+
|
9
|
+
* Ensure that the :uniq option for has_many :through associations retains the order. #10463 [remvee]
|
10
|
+
|
11
|
+
* Base.exists? doesn't rescue exceptions to avoid hiding SQL errors. #10458 [Michael Klishin]
|
12
|
+
|
13
|
+
* Documentation: Active Record exceptions, destroy_all and delete_all. #10444, #10447 [Michael Klishin]
|
14
|
+
|
15
|
+
|
1
16
|
*2.0.1* (December 7th, 2007)
|
2
17
|
|
3
18
|
* Removed query cache rescue as it could cause code to be run twice (closes #10408) [DHH]
|
@@ -9,7 +24,8 @@
|
|
9
24
|
|
10
25
|
* Fixed that the Query Cache should just be ignored if the database is misconfigured (so that the "About your applications environment" works even before the database has been created) [DHH]
|
11
26
|
|
12
|
-
* Fixed that the truncation of strings longer than 50 chars should use inspect
|
27
|
+
* Fixed that the truncation of strings longer than 50 chars should use inspect
|
28
|
+
so newlines etc are escaped #10385 [Norbert Crombach]
|
13
29
|
|
14
30
|
* Fixed that habtm associations should be able to set :select as part of their definition and have that honored [DHH]
|
15
31
|
|
@@ -25,7 +41,7 @@
|
|
25
41
|
|
26
42
|
render :partial => @client.becomes(Company) # renders companies/company instead of clients/client
|
27
43
|
|
28
|
-
* Fixed that to_xml should not automatically pass :procs to associations included with :include #10162 [
|
44
|
+
* Fixed that to_xml should not automatically pass :procs to associations included with :include #10162 [Cheah Chu Yeow]
|
29
45
|
|
30
46
|
* Fix documentation typo introduced in [8250]. Closes #10339 [Henrik N]
|
31
47
|
|
@@ -59,13 +75,13 @@
|
|
59
75
|
|
60
76
|
* Enhance explanation with more examples for attr_accessible macro. Closes #8095 [fearoffish, Marcel Molina]
|
61
77
|
|
62
|
-
* Update association/method mapping table to refected latest collection methods for has_many :through. Closes #8772 [
|
78
|
+
* Update association/method mapping table to refected latest collection methods for has_many :through. Closes #8772 [Pratik Naik]
|
63
79
|
|
64
80
|
* Explain semantics of having several different AR instances in a transaction block. Closes #9036 [jacobat, Marcel Molina]
|
65
81
|
|
66
82
|
* Update Schema documentation to use updated sexy migration notation. Closes #10086 [sjgman9]
|
67
83
|
|
68
|
-
* Make fixtures work with the new test subclasses. [
|
84
|
+
* Make fixtures work with the new test subclasses. [Tarmo Tänav, Koz]
|
69
85
|
|
70
86
|
* Introduce finder :joins with associations. Same :include syntax but with inner rather than outer joins. #10012 [RubyRedRick]
|
71
87
|
# Find users with an avatar
|
@@ -74,7 +90,7 @@
|
|
74
90
|
# Find posts with a high-rated comment.
|
75
91
|
Post.find(:all, :joins => :comments, :conditions => 'comments.rating > 3')
|
76
92
|
|
77
|
-
* Associations: speedup duplicate record check. #10011 [
|
93
|
+
* Associations: speedup duplicate record check. #10011 [Pratik Naik]
|
78
94
|
|
79
95
|
* Make sure that << works on has_many associations on unsaved records. Closes #9989 [hasmanyjosh]
|
80
96
|
|
@@ -93,13 +109,13 @@
|
|
93
109
|
|
94
110
|
* Add docs explaining how to protect all attributes using attr_accessible with no arguments. Closes #9631 [boone, rmm5t]
|
95
111
|
|
96
|
-
* Update add_index documentation to use new options api. Closes #9787 [
|
112
|
+
* Update add_index documentation to use new options api. Closes #9787 [Kamal Fariz Mahyuddin]
|
97
113
|
|
98
114
|
* Allow find on a has_many association defined with :finder_sql to accept id arguments as strings like regular find does. Closes #9916 [krishna]
|
99
115
|
|
100
116
|
* Use VALID_FIND_OPTIONS when resolving :find scoping rather than hard coding the list of valid find options. Closes #9443 [sur]
|
101
117
|
|
102
|
-
* Limited eager loading no longer ignores scoped :order. Closes #9561 [danger,
|
118
|
+
* Limited eager loading no longer ignores scoped :order. Closes #9561 [danger, Josh Peek]
|
103
119
|
|
104
120
|
* Assigning an instance of a foreign class to a composed_of aggregate calls an optional conversion block. Refactor and simplify composed_of implementation. #6322 [brandon, Chris Cruft]
|
105
121
|
|
@@ -116,11 +132,11 @@
|
|
116
132
|
|
117
133
|
* Fix regression where the association would not construct new finder SQL on save causing bogus queries for "WHERE owner_id = NULL" even after owner was saved. #8713 [Bryan Helmkamp]
|
118
134
|
|
119
|
-
* Refactor association create and build so before & after callbacks behave consistently. #8854 [
|
135
|
+
* Refactor association create and build so before & after callbacks behave consistently. #8854 [Pratik Naik, mortent]
|
120
136
|
|
121
137
|
* Quote table names. Defaults to column quoting. #4593 [Justin Lynn, gwcoffey, eadz, Dmitry V. Sabanin, Jeremy Kemper]
|
122
138
|
|
123
|
-
* Alias association #build to #new so it behaves predictably. #8787 [
|
139
|
+
* Alias association #build to #new so it behaves predictably. #8787 [Pratik Naik]
|
124
140
|
|
125
141
|
* Add notes to documentation regarding attr_readonly behavior with counter caches and polymorphic associations. Closes #9835 [saimonmoore, rick]
|
126
142
|
|
@@ -141,9 +157,9 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
141
157
|
|
142
158
|
* Speedup database date/time parsing. [Jeremy Kemper, Tarmo Tänav]
|
143
159
|
|
144
|
-
* Fix calling .clear on a has_many :dependent=>:delete_all association. [
|
160
|
+
* Fix calling .clear on a has_many :dependent=>:delete_all association. [Tarmo Tänav]
|
145
161
|
|
146
|
-
* Allow change_column to set NOT NULL in the PostgreSQL adapter [
|
162
|
+
* Allow change_column to set NOT NULL in the PostgreSQL adapter [Tarmo Tänav]
|
147
163
|
|
148
164
|
* Fix that ActiveRecord would create attribute methods and override custom attribute getters if the method is also defined in Kernel.methods. [Rick]
|
149
165
|
|
@@ -171,7 +187,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
171
187
|
|
172
188
|
* Extract Oracle, SQLServer, and Sybase adapters into gems. [Jeremy Kemper]
|
173
189
|
|
174
|
-
* Added fixture caching that'll speed up a normal fixture-powered test suite between 50% and 100% #9682 [
|
190
|
+
* Added fixture caching that'll speed up a normal fixture-powered test suite between 50% and 100% #9682 [Frederick Cheung]
|
175
191
|
|
176
192
|
* Correctly quote id list for limited eager loading. #7482 [tmacedo]
|
177
193
|
|
@@ -179,9 +195,9 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
179
195
|
|
180
196
|
* Fixed rename_column for SQLite when using symbols for the column names #8616 [drodriguez]
|
181
197
|
|
182
|
-
* Added the possibility of using symbols in addition to concrete classes with ActiveRecord::Observer#observe
|
198
|
+
* Added the possibility of using symbols in addition to concrete classes with ActiveRecord::Observer#observe. #3998 [Robby Russell, Tarmo Tänav]
|
183
199
|
|
184
|
-
* Added ActiveRecord::Base#to_json/from_json [DHH
|
200
|
+
* Added ActiveRecord::Base#to_json/from_json [DHH, Cheah Chu Yeow]
|
185
201
|
|
186
202
|
* Added ActiveRecord::Base#from_xml [DHH]. Example:
|
187
203
|
|
@@ -210,11 +226,11 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
210
226
|
|
211
227
|
* OpenBase: update for new lib and latest Rails. Support migrations. #8748 [dcsesq]
|
212
228
|
|
213
|
-
* Moved acts_as_tree into a plugin of the same name on the official Rails svn
|
229
|
+
* Moved acts_as_tree into a plugin of the same name on the official Rails svn. #9514 [Pratik Naik]
|
214
230
|
|
215
|
-
* Moved acts_as_nested_set into a plugin of the same name on the official Rails svn
|
231
|
+
* Moved acts_as_nested_set into a plugin of the same name on the official Rails svn. #9516 [Josh Peek]
|
216
232
|
|
217
|
-
* Moved acts_as_list into a plugin of the same name on the official Rails svn
|
233
|
+
* Moved acts_as_list into a plugin of the same name on the official Rails svn. [Josh Peek]
|
218
234
|
|
219
235
|
* Explicitly require active_record/query_cache before using it. [Jeremy Kemper]
|
220
236
|
|
@@ -240,7 +256,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
240
256
|
|
241
257
|
* Perform a deep #dup on query cache results so that modifying activerecord attributes does not modify the cached attributes. [Rick]
|
242
258
|
|
243
|
-
# Ensure that has_many :through associations use a count query instead of loading the target when #size is called. Closes #8800 [
|
259
|
+
# Ensure that has_many :through associations use a count query instead of loading the target when #size is called. Closes #8800 [Pratik Naik]
|
244
260
|
|
245
261
|
* Added :unless clause to validations #8003 [monki]. Example:
|
246
262
|
|
@@ -252,11 +268,11 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
252
268
|
validates_presence_of :username, :unless => using_open_id?
|
253
269
|
validates_presence_of :password, :unless => using_open_id?
|
254
270
|
|
255
|
-
* Fix #count on a has_many :through association so that it recognizes the :uniq option. Closes #8801 [
|
271
|
+
* Fix #count on a has_many :through association so that it recognizes the :uniq option. Closes #8801 [Pratik Naik]
|
256
272
|
|
257
|
-
* Fix and properly document/test count(column_name) usage. Closes #8999 [
|
273
|
+
* Fix and properly document/test count(column_name) usage. Closes #8999 [Pratik Naik]
|
258
274
|
|
259
|
-
* Remove deprecated count(conditions=nil, joins=nil) usage. Closes #8993 [
|
275
|
+
* Remove deprecated count(conditions=nil, joins=nil) usage. Closes #8993 [Pratik Naik]
|
260
276
|
|
261
277
|
* Change belongs_to so that the foreign_key assumption is taken from the association name, not the class name. Closes #8992 [hasmanyjosh]
|
262
278
|
|
@@ -266,25 +282,25 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
266
282
|
NEW
|
267
283
|
belongs_to :visitor, :class_name => 'User' # => inferred foreign_key is visitor_id
|
268
284
|
|
269
|
-
* Remove spurious tests from deprecated_associations_test, most of these aren't deprecated, and are duplicated in associations_test. Closes #8987 [
|
285
|
+
* Remove spurious tests from deprecated_associations_test, most of these aren't deprecated, and are duplicated in associations_test. Closes #8987 [Pratik Naik]
|
270
286
|
|
271
|
-
* Make create! on a has_many :through association return the association object. Not the collection. Closes #8786 [
|
287
|
+
* Make create! on a has_many :through association return the association object. Not the collection. Closes #8786 [Pratik Naik]
|
272
288
|
|
273
289
|
* Move from select * to select tablename.* to avoid clobbering IDs. Closes #8889 [dasil003]
|
274
290
|
|
275
291
|
* Don't call unsupported methods on associated objects when using :include, :method with to_xml #7307, [manfred, jwilger]
|
276
292
|
|
277
|
-
* Define collection singular ids method for has_many :through associations. #8763 [
|
293
|
+
* Define collection singular ids method for has_many :through associations. #8763 [Pratik Naik]
|
278
294
|
|
279
|
-
* Array attribute conditions work with proxied association collections. #8318 [
|
295
|
+
* Array attribute conditions work with proxied association collections. #8318 [Kamal Fariz Mahyuddin, theamazingrando]
|
280
296
|
|
281
|
-
* Fix polymorphic has_one associations declared in an abstract class. #8638 [
|
297
|
+
* Fix polymorphic has_one associations declared in an abstract class. #8638 [Pratik Naik, Dax Huiberts]
|
282
298
|
|
283
|
-
* Fixed validates_associated should not stop on the first error
|
299
|
+
* Fixed validates_associated should not stop on the first error. #4276 [mrj, Manfred Stienstra, Josh Peek]
|
284
300
|
|
285
301
|
* Rollback if commit raises an exception. #8642 [kik, Jeremy Kemper]
|
286
302
|
|
287
|
-
* Update tests' use of fixtures for the new collections api. #8726 [
|
303
|
+
* Update tests' use of fixtures for the new collections api. #8726 [Kamal Fariz Mahyuddin]
|
288
304
|
|
289
305
|
* Save associated records only if the association is already loaded. #8713 [blaine]
|
290
306
|
|
@@ -294,7 +310,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
294
310
|
|
295
311
|
* Fixtures: people(:technomancy, :josh) returns both fixtures. #7880 [technomancy, Josh Peek]
|
296
312
|
|
297
|
-
* Calculations support non-numeric foreign keys. #8154 [
|
313
|
+
* Calculations support non-numeric foreign keys. #8154 [Kamal Fariz Mahyuddin]
|
298
314
|
|
299
315
|
* with_scope is protected. #8524 [Josh Peek]
|
300
316
|
|
@@ -330,7 +346,7 @@ single-table inheritance. #3833, #9886 [Gabriel Gironda, rramdas, François Bea
|
|
330
346
|
|
331
347
|
* Load database adapters on demand. Eliminates config.connection_adapters and RAILS_CONNECTION_ADAPTERS. Add your lib directory to the $LOAD_PATH and put your custom adapter in lib/active_record/connection_adapters/adaptername_adapter.rb. This way you can provide custom adapters as plugins or gems without modifying Rails. [Jeremy Kemper]
|
332
348
|
|
333
|
-
* Ensure that associations with :dependent => :delete_all respect :conditions option. Closes #8034 [danger,
|
349
|
+
* Ensure that associations with :dependent => :delete_all respect :conditions option. Closes #8034 [danger, Josh Peek, Rick]
|
334
350
|
|
335
351
|
* belongs_to assignment creates a new proxy rather than modifying its target in-place. #8412 [mmangino@elevatedrails.com]
|
336
352
|
|
@@ -733,7 +749,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing]
|
|
733
749
|
|
734
750
|
* Fixed to_xml with :include misbehaviors when invoked on array of model instances #5690 [alexkwolfe@gmail.com]
|
735
751
|
|
736
|
-
* Added support for conditions on Base.exists? #5689 [
|
752
|
+
* Added support for conditions on Base.exists? #5689 [Josh Peek]. Examples:
|
737
753
|
|
738
754
|
assert (Topic.exists?(:author_name => "David"))
|
739
755
|
assert (Topic.exists?(:author_name => "Mary", :approved => true))
|
@@ -1190,7 +1206,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing]
|
|
1190
1206
|
|
1191
1207
|
* Fixed to_xml with :include misbehaviors when invoked on array of model instances #5690 [alexkwolfe@gmail.com]
|
1192
1208
|
|
1193
|
-
* Added support for conditions on Base.exists? #5689 [
|
1209
|
+
* Added support for conditions on Base.exists? #5689 [Josh Peek]. Examples:
|
1194
1210
|
|
1195
1211
|
assert (Topic.exists?(:author_name => "David"))
|
1196
1212
|
assert (Topic.exists?(:author_name => "Mary", :approved => true))
|
data/README
CHANGED
@@ -65,20 +65,6 @@ A short rundown of the major features:
|
|
65
65
|
end
|
66
66
|
|
67
67
|
{Learn more}[link:classes/ActiveRecord/Validations.html]
|
68
|
-
|
69
|
-
|
70
|
-
* Acts that can make records work as lists or trees:
|
71
|
-
|
72
|
-
class Item < ActiveRecord::Base
|
73
|
-
belongs_to :list
|
74
|
-
acts_as_list :scope => :list
|
75
|
-
end
|
76
|
-
|
77
|
-
item.move_higher
|
78
|
-
item.move_to_bottom
|
79
|
-
|
80
|
-
Learn about {acts_as_list}[link:classes/ActiveRecord/Acts/List/ClassMethods.html], {the instance methods acts_as_list provides}[link:classes/ActiveRecord/Acts/List/InstanceMethods.html], and
|
81
|
-
{acts_as_tree}[link:classes/ActiveRecord/Acts/Tree/ClassMethods.html]
|
82
68
|
|
83
69
|
* Callbacks as methods or queues on the entire lifecycle (instantiation, saving, destroying, validating, etc).
|
84
70
|
|
data/Rakefile
CHANGED
@@ -162,6 +162,7 @@ end
|
|
162
162
|
dist_dirs = [ "lib", "test", "examples" ]
|
163
163
|
|
164
164
|
spec = Gem::Specification.new do |s|
|
165
|
+
s.platform = Gem::Platform::RUBY
|
165
166
|
s.name = PKG_NAME
|
166
167
|
s.version = PKG_VERSION
|
167
168
|
s.summary = "Implements the ActiveRecord pattern for ORM."
|
@@ -172,7 +173,7 @@ spec = Gem::Specification.new do |s|
|
|
172
173
|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
173
174
|
end
|
174
175
|
|
175
|
-
s.add_dependency('activesupport', '= 2.0.
|
176
|
+
s.add_dependency('activesupport', '= 2.0.2' + PKG_BUILD)
|
176
177
|
|
177
178
|
s.files.delete "test/fixtures/fixture_database.sqlite"
|
178
179
|
s.files.delete "test/fixtures/fixture_database_2.sqlite"
|
@@ -12,15 +12,15 @@ module ActiveRecord
|
|
12
12
|
Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
|
13
13
|
reset
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def proxy_owner
|
17
17
|
@owner
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def proxy_reflection
|
21
21
|
@reflection
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def proxy_target
|
25
25
|
@target
|
26
26
|
end
|
@@ -28,23 +28,23 @@ module ActiveRecord
|
|
28
28
|
def respond_to?(symbol, include_priv = false)
|
29
29
|
proxy_respond_to?(symbol, include_priv) || (load_target && @target.respond_to?(symbol, include_priv))
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# Explicitly proxy === because the instance method removal above
|
33
33
|
# doesn't catch it.
|
34
34
|
def ===(other)
|
35
35
|
load_target
|
36
36
|
other === @target
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def aliased_table_name
|
40
40
|
@reflection.klass.table_name
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
def conditions
|
44
44
|
@conditions ||= interpolate_sql(sanitize_sql(@reflection.options[:conditions])) if @reflection.options[:conditions]
|
45
45
|
end
|
46
46
|
alias :sql_conditions :conditions
|
47
|
-
|
47
|
+
|
48
48
|
def reset
|
49
49
|
@loaded = false
|
50
50
|
@target = nil
|
@@ -53,25 +53,26 @@ module ActiveRecord
|
|
53
53
|
def reload
|
54
54
|
reset
|
55
55
|
load_target
|
56
|
+
self unless @target.nil?
|
56
57
|
end
|
57
58
|
|
58
59
|
def loaded?
|
59
60
|
@loaded
|
60
61
|
end
|
61
|
-
|
62
|
+
|
62
63
|
def loaded
|
63
64
|
@loaded = true
|
64
65
|
end
|
65
|
-
|
66
|
+
|
66
67
|
def target
|
67
68
|
@target
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
def target=(target)
|
71
72
|
@target = target
|
72
73
|
loaded
|
73
74
|
end
|
74
|
-
|
75
|
+
|
75
76
|
def inspect
|
76
77
|
reload unless loaded?
|
77
78
|
@target.inspect
|
@@ -81,7 +82,7 @@ module ActiveRecord
|
|
81
82
|
def dependent?
|
82
83
|
@reflection.options[:dependent]
|
83
84
|
end
|
84
|
-
|
85
|
+
|
85
86
|
def quoted_record_ids(records)
|
86
87
|
records.map { |record| record.quoted_id }.join(',')
|
87
88
|
end
|
@@ -117,10 +118,10 @@ module ActiveRecord
|
|
117
118
|
:select => @reflection.options[:select]
|
118
119
|
)
|
119
120
|
end
|
120
|
-
|
121
|
+
|
121
122
|
private
|
122
123
|
def method_missing(method, *args, &block)
|
123
|
-
if load_target
|
124
|
+
if load_target
|
124
125
|
@target.send(method, *args, &block)
|
125
126
|
end
|
126
127
|
end
|
@@ -148,7 +148,8 @@ module ActiveRecord
|
|
148
148
|
:include => @reflection.options[:include] || @reflection.source_reflection.options[:include]
|
149
149
|
)
|
150
150
|
|
151
|
-
@reflection.options[:uniq]
|
151
|
+
records.uniq! if @reflection.options[:uniq]
|
152
|
+
records
|
152
153
|
end
|
153
154
|
|
154
155
|
# Construct attributes for associate pointing to owner.
|
data/lib/active_record/base.rb
CHANGED
@@ -3,39 +3,98 @@ require 'yaml'
|
|
3
3
|
require 'set'
|
4
4
|
|
5
5
|
module ActiveRecord #:nodoc:
|
6
|
-
|
6
|
+
# Generic ActiveRecord exception class.
|
7
|
+
class ActiveRecordError < StandardError
|
7
8
|
end
|
9
|
+
|
10
|
+
# Raised when the single-table inheritance mechanism failes to locate the subclass
|
11
|
+
# (for example due to improper usage of column that +inheritance_column+ points to).
|
8
12
|
class SubclassNotFound < ActiveRecordError #:nodoc:
|
9
13
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
14
|
+
|
15
|
+
# Raised when object assigned to association is of incorrect type.
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
#
|
19
|
+
# class Ticket < ActiveRecord::Base
|
20
|
+
# has_many :patches
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# class Patch < ActiveRecord::Base
|
24
|
+
# belongs_to :ticket
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# and somewhere in the code:
|
28
|
+
#
|
29
|
+
# @ticket.patches << Comment.new(:content => "Please attach tests to your patch.")
|
30
|
+
# @ticket.save
|
31
|
+
class AssociationTypeMismatch < ActiveRecordError
|
13
32
|
end
|
14
|
-
|
33
|
+
|
34
|
+
# Raised when unserialized object's type mismatches one specified for serializable field.
|
35
|
+
class SerializationTypeMismatch < ActiveRecordError
|
15
36
|
end
|
16
|
-
|
37
|
+
|
38
|
+
# Raised when adapter not specified on connection (or configuration file config/database.yml misses adapter field).
|
39
|
+
class AdapterNotSpecified < ActiveRecordError
|
17
40
|
end
|
18
|
-
|
41
|
+
|
42
|
+
# Raised when ActiveRecord cannot find database adapter specified in config/database.yml or programmatically.
|
43
|
+
class AdapterNotFound < ActiveRecordError
|
19
44
|
end
|
20
|
-
|
45
|
+
|
46
|
+
# Raised when connection to the database could not been established (for example when connection= is given a nil object).
|
47
|
+
class ConnectionNotEstablished < ActiveRecordError
|
21
48
|
end
|
22
|
-
|
49
|
+
|
50
|
+
# Raised when ActiveRecord cannot find record by given id or set of ids.
|
51
|
+
class RecordNotFound < ActiveRecordError
|
23
52
|
end
|
24
|
-
|
53
|
+
|
54
|
+
# Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
|
55
|
+
# saved because record is invalid.
|
56
|
+
class RecordNotSaved < ActiveRecordError
|
25
57
|
end
|
26
|
-
|
58
|
+
|
59
|
+
# Raised when SQL statement cannot be executed by the database (for example, it's often the case for MySQL when Ruby driver used is too old).
|
60
|
+
class StatementInvalid < ActiveRecordError
|
27
61
|
end
|
28
|
-
|
62
|
+
|
63
|
+
# Raised when number of bind variables in statement given to :condition key (for example, when using +find+ method)
|
64
|
+
# does not match number of expected variables.
|
65
|
+
#
|
66
|
+
# Example:
|
67
|
+
#
|
68
|
+
# Location.find :all, :conditions => ["lat = ? AND lng = ?", 53.7362]
|
69
|
+
#
|
70
|
+
# in example above two placeholders are given but only one variable to fill them.
|
71
|
+
class PreparedStatementInvalid < ActiveRecordError
|
29
72
|
end
|
30
|
-
|
73
|
+
|
74
|
+
# Raised on attempt to save stale record. Record is stale when it's being saved in another query after
|
75
|
+
# instantiation, for example, when two users edit the same wiki page and one starts editing and saves
|
76
|
+
# the page before the other.
|
77
|
+
#
|
78
|
+
# Read more about optimistic locking in +ActiveRecord::Locking+ module RDoc.
|
79
|
+
class StaleObjectError < ActiveRecordError
|
31
80
|
end
|
32
|
-
|
81
|
+
|
82
|
+
# Raised when association is being configured improperly or
|
83
|
+
# user tries to use offset and limit together with has_many or has_and_belongs_to_many associations.
|
84
|
+
class ConfigurationError < ActiveRecordError
|
33
85
|
end
|
34
|
-
|
86
|
+
|
87
|
+
# Raised on attempt to update record that is instantiated as read only.
|
88
|
+
class ReadOnlyRecord < ActiveRecordError
|
35
89
|
end
|
36
|
-
|
90
|
+
|
91
|
+
# Used by ActiveRecord transaction mechanism to distinguish rollback from other exceptional situations.
|
92
|
+
# You can use it to roll your transaction back explicitly in the block passed to +transaction+ method.
|
93
|
+
class Rollback < ActiveRecordError
|
37
94
|
end
|
38
|
-
|
95
|
+
|
96
|
+
# Raised when attribute has a name reserved by ActiveRecord (when attribute has name of one of ActiveRecord instance methods).
|
97
|
+
class DangerousAttributeError < ActiveRecordError
|
39
98
|
end
|
40
99
|
|
41
100
|
# Raised when you've tried to access a column which wasn't
|
@@ -111,7 +170,7 @@ module ActiveRecord #:nodoc:
|
|
111
170
|
#
|
112
171
|
# The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query and is thus susceptible to SQL-injection
|
113
172
|
# attacks if the <tt>user_name</tt> and +password+ parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
|
114
|
-
# <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+ before inserting them in the query,
|
173
|
+
# <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+ before inserting them in the query,
|
115
174
|
# which will ensure that an attacker can't escape the query and fake the login (or worse).
|
116
175
|
#
|
117
176
|
# When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth
|
@@ -159,7 +218,7 @@ module ActiveRecord #:nodoc:
|
|
159
218
|
#
|
160
219
|
# In addition to the basic accessors, query methods are also automatically available on the Active Record object.
|
161
220
|
# Query methods allow you to test whether an attribute value is present.
|
162
|
-
#
|
221
|
+
#
|
163
222
|
# For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
|
164
223
|
# to determine whether the user has a name:
|
165
224
|
#
|
@@ -201,7 +260,7 @@ module ActiveRecord #:nodoc:
|
|
201
260
|
#
|
202
261
|
# # No 'Summer' tag exists
|
203
262
|
# Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
|
204
|
-
#
|
263
|
+
#
|
205
264
|
# # Now the 'Summer' tag does exist
|
206
265
|
# Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
|
207
266
|
#
|
@@ -364,7 +423,7 @@ module ActiveRecord #:nodoc:
|
|
364
423
|
|
365
424
|
# Specifies the format to use when dumping the database schema with Rails'
|
366
425
|
# Rakefile. If :sql, the schema is dumped as (potentially database-
|
367
|
-
# specific) SQL statements. If :ruby, the schema is dumped as an
|
426
|
+
# specific) SQL statements. If :ruby, the schema is dumped as an
|
368
427
|
# ActiveRecord::Schema file which can be loaded into any database that
|
369
428
|
# supports migrations. Use :ruby if you want to have different database
|
370
429
|
# adapters for, e.g., your development and test environments.
|
@@ -387,17 +446,16 @@ module ActiveRecord #:nodoc:
|
|
387
446
|
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
|
388
447
|
# * <tt>:limit</tt>: An integer determining the limit on the number of rows that should be returned.
|
389
448
|
# * <tt>:offset</tt>: An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
|
390
|
-
# * <tt>:joins</tt>:
|
391
|
-
#
|
392
|
-
#
|
449
|
+
# * <tt>:joins</tt>: Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed)
|
450
|
+
# or named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s).
|
451
|
+
# If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table's columns.
|
393
452
|
# Pass :readonly => false to override.
|
394
|
-
# See adding joins for associations under Associations.
|
395
453
|
# * <tt>:include</tt>: Names associations that should be loaded alongside using LEFT OUTER JOINs. The symbols named refer
|
396
454
|
# to already defined associations. See eager loading under Associations.
|
397
455
|
# * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not
|
398
456
|
# include the joined columns.
|
399
457
|
# * <tt>:from</tt>: By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
|
400
|
-
# of a database view).
|
458
|
+
# of a database view).
|
401
459
|
# * <tt>:readonly</tt>: Mark the returned records read-only so they cannot be saved or updated.
|
402
460
|
# * <tt>:lock</tt>: An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE".
|
403
461
|
# :lock => true gives connection's default exclusive lock, usually "FOR UPDATE".
|
@@ -437,13 +495,6 @@ module ActiveRecord #:nodoc:
|
|
437
495
|
# end
|
438
496
|
def find(*args)
|
439
497
|
options = args.extract_options!
|
440
|
-
# Note: we extract any :joins option with a non-string value from the options, and turn it into
|
441
|
-
# an internal option :ar_joins. This allows code called from here to find the ar_joins, and
|
442
|
-
# it bypasses marking the result as read_only.
|
443
|
-
# A normal string join marks the result as read-only because it contains attributes from joined tables
|
444
|
-
# which are not in the base table and therefore prevent the result from being saved.
|
445
|
-
# In the case of an ar_join, the JoinDependency created to instantiate the results eliminates these
|
446
|
-
# bogus attributes. See JoinDependency#instantiate, and JoinBase#instantiate in associations.rb.
|
447
498
|
validate_find_options(options)
|
448
499
|
set_readonly_option!(options)
|
449
500
|
|
@@ -453,20 +504,20 @@ module ActiveRecord #:nodoc:
|
|
453
504
|
else find_from_ids(args, options)
|
454
505
|
end
|
455
506
|
end
|
456
|
-
|
507
|
+
|
457
508
|
#
|
458
|
-
# Executes a custom sql query against your database and returns all the results. The results will
|
459
|
-
# be returned as an array with columns requested encapsulated as attributes of the model you call
|
460
|
-
# this method from. If you call +Product.find_by_sql+ then the results will be returned in a Product
|
509
|
+
# Executes a custom sql query against your database and returns all the results. The results will
|
510
|
+
# be returned as an array with columns requested encapsulated as attributes of the model you call
|
511
|
+
# this method from. If you call +Product.find_by_sql+ then the results will be returned in a Product
|
461
512
|
# object with the attributes you specified in the SQL query.
|
462
513
|
#
|
463
|
-
# If you call a complicated SQL query which spans multiple tables the columns specified by the
|
464
|
-
# SELECT will be attributes of the model, whether or not they are columns of the corresponding
|
514
|
+
# If you call a complicated SQL query which spans multiple tables the columns specified by the
|
515
|
+
# SELECT will be attributes of the model, whether or not they are columns of the corresponding
|
465
516
|
# table.
|
466
517
|
#
|
467
|
-
# The +sql+ parameter is a full sql query as a string. It will be called as is, there will be
|
468
|
-
# no database agnostic conversions performed. This should be a last resort because using, for example,
|
469
|
-
# MySQL specific terms will lock you to using that particular database engine or require you to
|
518
|
+
# The +sql+ parameter is a full sql query as a string. It will be called as is, there will be
|
519
|
+
# no database agnostic conversions performed. This should be a last resort because using, for example,
|
520
|
+
# MySQL specific terms will lock you to using that particular database engine or require you to
|
470
521
|
# change your call if you switch engines
|
471
522
|
#
|
472
523
|
# ==== Examples
|
@@ -481,15 +532,15 @@ module ActiveRecord #:nodoc:
|
|
481
532
|
connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
|
482
533
|
end
|
483
534
|
|
484
|
-
# Checks whether a record exists in the database that matches conditions given. These conditions
|
485
|
-
# can either be a single integer representing a primary key id to be found, or a condition to be
|
535
|
+
# Checks whether a record exists in the database that matches conditions given. These conditions
|
536
|
+
# can either be a single integer representing a primary key id to be found, or a condition to be
|
486
537
|
# matched like using ActiveRecord#find.
|
487
538
|
#
|
488
|
-
# The +id_or_conditions+ parameter can be an Integer or a String if you want to search the primary key
|
489
|
-
# column of the table for a matching id, or if you're looking to match against a condition you can use
|
539
|
+
# The +id_or_conditions+ parameter can be an Integer or a String if you want to search the primary key
|
540
|
+
# column of the table for a matching id, or if you're looking to match against a condition you can use
|
490
541
|
# an Array or a Hash.
|
491
542
|
#
|
492
|
-
# Possible gotcha: You can't pass in a condition as a string e.g. "name = 'Jamie'", this would be
|
543
|
+
# Possible gotcha: You can't pass in a condition as a string e.g. "name = 'Jamie'", this would be
|
493
544
|
# sanitized and then queried against the primary key column as "id = 'name = \'Jamie"
|
494
545
|
#
|
495
546
|
# ==== Examples
|
@@ -498,12 +549,11 @@ module ActiveRecord #:nodoc:
|
|
498
549
|
# Person.exists?(:name => "David")
|
499
550
|
# Person.exists?(['name LIKE ?', "%#{query}%"])
|
500
551
|
def exists?(id_or_conditions)
|
501
|
-
!find(:first, :select => "#{
|
502
|
-
|
503
|
-
false
|
552
|
+
!find(:first, :select => "#{quoted_table_name}.#{primary_key}",
|
553
|
+
:conditions => expand_id_conditions(id_or_conditions)).nil?
|
504
554
|
end
|
505
555
|
|
506
|
-
# Creates an object (or multiple objects) and saves it to the database, if validations pass.
|
556
|
+
# Creates an object (or multiple objects) and saves it to the database, if validations pass.
|
507
557
|
# The resulting object is returned whether the object was saved successfully to the database or not.
|
508
558
|
#
|
509
559
|
# The +attributes+ parameter can be either be a Hash or an Array of Hashes. These Hashes describe the
|
@@ -536,9 +586,9 @@ module ActiveRecord #:nodoc:
|
|
536
586
|
#
|
537
587
|
# # Updating one record:
|
538
588
|
# Person.update(15, {:user_name => 'Samuel', :group => 'expert'})
|
539
|
-
#
|
589
|
+
#
|
540
590
|
# # Updating multiple records:
|
541
|
-
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy"} }
|
591
|
+
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy"} }
|
542
592
|
# Person.update(people.keys, people.values)
|
543
593
|
def update(id, attributes)
|
544
594
|
if id.is_a?(Array)
|
@@ -554,18 +604,18 @@ module ActiveRecord #:nodoc:
|
|
554
604
|
# Delete an object (or multiple objects) where the +id+ given matches the primary_key. A SQL +DELETE+ command
|
555
605
|
# is executed on the database which means that no callbacks are fired off running this. This is an efficient method
|
556
606
|
# of deleting records that don't need cleaning up after or other actions to be taken.
|
557
|
-
#
|
607
|
+
#
|
558
608
|
# Objects are _not_ instantiated with this method.
|
559
609
|
#
|
560
610
|
# ==== Options
|
561
|
-
#
|
611
|
+
#
|
562
612
|
# +id+ Can be either an Integer or an Array of Integers
|
563
613
|
#
|
564
614
|
# ==== Examples
|
565
615
|
#
|
566
616
|
# # Delete a single object
|
567
617
|
# Todo.delete(1)
|
568
|
-
#
|
618
|
+
#
|
569
619
|
# # Delete multiple objects
|
570
620
|
# todos = [1,2,3]
|
571
621
|
# Todo.delete(todos)
|
@@ -576,19 +626,19 @@ module ActiveRecord #:nodoc:
|
|
576
626
|
# Destroy an object (or multiple objects) that has the given id, the object is instantiated first,
|
577
627
|
# therefore all callbacks and filters are fired off before the object is deleted. This method is
|
578
628
|
# less efficient than ActiveRecord#delete but allows cleanup methods and other actions to be run.
|
579
|
-
#
|
580
|
-
# This essentially finds the object (or multiple objects) with the given id, creates a new object
|
629
|
+
#
|
630
|
+
# This essentially finds the object (or multiple objects) with the given id, creates a new object
|
581
631
|
# from the attributes, and then calls destroy on it.
|
582
632
|
#
|
583
633
|
# ==== Options
|
584
|
-
#
|
634
|
+
#
|
585
635
|
# +id+ Can be either an Integer or an Array of Integers
|
586
636
|
#
|
587
637
|
# ==== Examples
|
588
638
|
#
|
589
639
|
# # Destroy a single object
|
590
640
|
# Todo.destroy(1)
|
591
|
-
#
|
641
|
+
#
|
592
642
|
# # Destroy multiple objects
|
593
643
|
# todos = [1,2,3]
|
594
644
|
# Todo.destroy(todos)
|
@@ -602,7 +652,7 @@ module ActiveRecord #:nodoc:
|
|
602
652
|
# ==== Options
|
603
653
|
#
|
604
654
|
# +updates+ A String of column and value pairs that will be set on any records that match conditions
|
605
|
-
# +conditions+ An SQL fragment like "administrator = 1" or [ "user_name = ?", username ].
|
655
|
+
# +conditions+ An SQL fragment like "administrator = 1" or [ "user_name = ?", username ].
|
606
656
|
# See conditions in the intro for more info.
|
607
657
|
# +options+ Additional options are :limit and/or :order, see the examples for usage.
|
608
658
|
#
|
@@ -610,12 +660,12 @@ module ActiveRecord #:nodoc:
|
|
610
660
|
#
|
611
661
|
# # Update all billing objects with the 3 different attributes given
|
612
662
|
# Billing.update_all( "category = 'authorized', approved = 1, author = 'David'" )
|
613
|
-
#
|
663
|
+
#
|
614
664
|
# # Update records that match our conditions
|
615
665
|
# Billing.update_all( "author = 'David'", "title LIKE '%Rails%'" )
|
616
666
|
#
|
617
667
|
# # Update records that match our conditions but limit it to 5 ordered by date
|
618
|
-
# Billing.update_all( "author = 'David'", "title LIKE '%Rails%'",
|
668
|
+
# Billing.update_all( "author = 'David'", "title LIKE '%Rails%'",
|
619
669
|
# :order => 'created_at', :limit => 5 )
|
620
670
|
def update_all(updates, conditions = nil, options = {})
|
621
671
|
sql = "UPDATE #{table_name} SET #{sanitize_sql_for_assignment(updates)} "
|
@@ -626,16 +676,39 @@ module ActiveRecord #:nodoc:
|
|
626
676
|
connection.update(sql, "#{name} Update")
|
627
677
|
end
|
628
678
|
|
629
|
-
# Destroys the
|
630
|
-
#
|
679
|
+
# Destroys the records matching +conditions+ by instantiating each record and calling the destroy method.
|
680
|
+
# This means at least 2*N database queries to destroy N records, so avoid destroy_all if you are deleting
|
681
|
+
# many records. If you want to simply delete records without worrying about dependent associations or
|
682
|
+
# callbacks, use the much faster +delete_all+ method instead.
|
683
|
+
#
|
684
|
+
# ==== Options
|
685
|
+
#
|
686
|
+
# +conditions+ Conditions are specified the same way as with +find+ method.
|
687
|
+
#
|
688
|
+
# ==== Example
|
689
|
+
#
|
631
690
|
# Person.destroy_all "last_login < '2004-04-04'"
|
691
|
+
#
|
692
|
+
# This loads and destroys each person one by one, including its dependent associations and before_ and
|
693
|
+
# after_destroy callbacks.
|
632
694
|
def destroy_all(conditions = nil)
|
633
695
|
find(:all, :conditions => conditions).each { |object| object.destroy }
|
634
696
|
end
|
635
697
|
|
636
|
-
# Deletes
|
637
|
-
# calling the destroy method
|
698
|
+
# Deletes the records matching +conditions+ without instantiating the records first, and hence not
|
699
|
+
# calling the destroy method and invoking callbacks. This is a single SQL query, much more efficient
|
700
|
+
# than destroy_all.
|
701
|
+
#
|
702
|
+
# ==== Options
|
703
|
+
#
|
704
|
+
# +conditions+ Conditions are specified the same way as with +find+ method.
|
705
|
+
#
|
706
|
+
# ==== Example
|
707
|
+
#
|
638
708
|
# Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')"
|
709
|
+
#
|
710
|
+
# This deletes the affected posts all at once with a single DELETE query. If you need to destroy dependent
|
711
|
+
# associations or call your before_ or after_destroy callbacks, use the +destroy_all+ method instead.
|
639
712
|
def delete_all(conditions = nil)
|
640
713
|
sql = "DELETE FROM #{quoted_table_name} "
|
641
714
|
add_conditions!(sql, conditions, scope(:find))
|
@@ -643,11 +716,11 @@ module ActiveRecord #:nodoc:
|
|
643
716
|
end
|
644
717
|
|
645
718
|
# Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
|
646
|
-
# The use of this method should be restricted to complicated SQL queries that can't be executed
|
719
|
+
# The use of this method should be restricted to complicated SQL queries that can't be executed
|
647
720
|
# using the ActiveRecord::Calculations class methods. Look into those before using this.
|
648
721
|
#
|
649
722
|
# ==== Options
|
650
|
-
#
|
723
|
+
#
|
651
724
|
# +sql+: An SQL statement which should return a count query from the database, see the example below
|
652
725
|
#
|
653
726
|
# ==== Examples
|
@@ -665,15 +738,15 @@ module ActiveRecord #:nodoc:
|
|
665
738
|
# given by the corresponding value:
|
666
739
|
#
|
667
740
|
# ==== Options
|
668
|
-
#
|
741
|
+
#
|
669
742
|
# +id+ The id of the object you wish to update a counter on
|
670
|
-
# +counters+ An Array of Hashes containing the names of the fields
|
743
|
+
# +counters+ An Array of Hashes containing the names of the fields
|
671
744
|
# to update as keys and the amount to update the field by as
|
672
745
|
# values
|
673
|
-
#
|
746
|
+
#
|
674
747
|
# ==== Examples
|
675
|
-
#
|
676
|
-
# # For the Post with id of 5, decrement the comment_count by 1, and
|
748
|
+
#
|
749
|
+
# # For the Post with id of 5, decrement the comment_count by 1, and
|
677
750
|
# # increment the action_count by 1
|
678
751
|
# Post.update_counters 5, :comment_count => -1, :action_count => 1
|
679
752
|
# # Executes the following SQL:
|
@@ -691,8 +764,8 @@ module ActiveRecord #:nodoc:
|
|
691
764
|
|
692
765
|
# Increment a number field by one, usually representing a count.
|
693
766
|
#
|
694
|
-
# This is used for caching aggregate values, so that they don't need to be computed every time.
|
695
|
-
# For example, a DiscussionBoard may cache post_count and comment_count otherwise every time the board is
|
767
|
+
# This is used for caching aggregate values, so that they don't need to be computed every time.
|
768
|
+
# For example, a DiscussionBoard may cache post_count and comment_count otherwise every time the board is
|
696
769
|
# shown it would have to run an SQL query to find how many posts and comments there are.
|
697
770
|
#
|
698
771
|
# ==== Options
|
@@ -752,14 +825,14 @@ module ActiveRecord #:nodoc:
|
|
752
825
|
read_inheritable_attribute("attr_protected")
|
753
826
|
end
|
754
827
|
|
755
|
-
# Similar to the attr_protected macro, this protects attributes of your model from mass-assignment,
|
828
|
+
# Similar to the attr_protected macro, this protects attributes of your model from mass-assignment,
|
756
829
|
# such as <tt>new(attributes)</tt> and <tt>attributes=(attributes)</tt>
|
757
|
-
# however, it does it in the opposite way. This locks all attributes and only allows access to the
|
758
|
-
# attributes specified. Assignment to attributes not in this list will be ignored and need to be set
|
759
|
-
# using the direct writer methods instead. This is meant to protect sensitive attributes from being
|
760
|
-
# overwritten by URL/form hackers. If you'd rather start from an all-open default and restrict
|
830
|
+
# however, it does it in the opposite way. This locks all attributes and only allows access to the
|
831
|
+
# attributes specified. Assignment to attributes not in this list will be ignored and need to be set
|
832
|
+
# using the direct writer methods instead. This is meant to protect sensitive attributes from being
|
833
|
+
# overwritten by URL/form hackers. If you'd rather start from an all-open default and restrict
|
761
834
|
# attributes as needed, have a look at attr_protected.
|
762
|
-
#
|
835
|
+
#
|
763
836
|
# ==== Options
|
764
837
|
#
|
765
838
|
# <tt>*attributes</tt> A comma separated list of symbols that represent columns _not_ to be protected
|
@@ -796,9 +869,9 @@ module ActiveRecord #:nodoc:
|
|
796
869
|
read_inheritable_attribute("attr_readonly")
|
797
870
|
end
|
798
871
|
|
799
|
-
# If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object,
|
800
|
-
# then specify the name of that attribute using this method and it will be handled automatically.
|
801
|
-
# The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that
|
872
|
+
# If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object,
|
873
|
+
# then specify the name of that attribute using this method and it will be handled automatically.
|
874
|
+
# The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that
|
802
875
|
# class on retrieval or +SerializationTypeMismatch+ will be raised.
|
803
876
|
#
|
804
877
|
# ==== Options
|
@@ -997,7 +1070,7 @@ module ActiveRecord #:nodoc:
|
|
997
1070
|
columns.size > 0
|
998
1071
|
rescue ActiveRecord::StatementInvalid
|
999
1072
|
false
|
1000
|
-
end
|
1073
|
+
end
|
1001
1074
|
end
|
1002
1075
|
end
|
1003
1076
|
|
@@ -1130,7 +1203,7 @@ module ActiveRecord #:nodoc:
|
|
1130
1203
|
# Overwrite the default class equality method to provide support for association proxies.
|
1131
1204
|
def ===(object)
|
1132
1205
|
object.is_a?(self)
|
1133
|
-
end
|
1206
|
+
end
|
1134
1207
|
|
1135
1208
|
# Returns the base AR subclass that this class descends from. If A
|
1136
1209
|
# extends AR::Base, A.base_class will return A. If B descends from A
|
@@ -1156,7 +1229,7 @@ module ActiveRecord #:nodoc:
|
|
1156
1229
|
|
1157
1230
|
def find_every(options)
|
1158
1231
|
records = scoped?(:find, :include) || options[:include] ?
|
1159
|
-
find_with_associations(options) :
|
1232
|
+
find_with_associations(options) :
|
1160
1233
|
find_by_sql(construct_finder_sql(options))
|
1161
1234
|
|
1162
1235
|
records.each { |record| record.readonly! } if options[:readonly]
|
@@ -1180,7 +1253,7 @@ module ActiveRecord #:nodoc:
|
|
1180
1253
|
find_some(ids, options)
|
1181
1254
|
end
|
1182
1255
|
end
|
1183
|
-
|
1256
|
+
|
1184
1257
|
def find_one(id, options)
|
1185
1258
|
conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
|
1186
1259
|
options.update :conditions => "#{quoted_table_name}.#{connection.quote_column_name(primary_key)} = #{quote_value(id,columns_hash[primary_key])}#{conditions}"
|
@@ -1194,7 +1267,7 @@ module ActiveRecord #:nodoc:
|
|
1194
1267
|
raise RecordNotFound, "Couldn't find #{name} with ID=#{id}#{conditions}"
|
1195
1268
|
end
|
1196
1269
|
end
|
1197
|
-
|
1270
|
+
|
1198
1271
|
def find_some(ids, options)
|
1199
1272
|
conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
|
1200
1273
|
ids_list = ids.map { |id| quote_value(id,columns_hash[primary_key]) }.join(',')
|
@@ -1397,7 +1470,7 @@ module ActiveRecord #:nodoc:
|
|
1397
1470
|
# It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount
|
1398
1471
|
# is actually find_all_by_amount(amount, options).
|
1399
1472
|
#
|
1400
|
-
# This also enables you to initialize a record if it is not found, such as find_or_initialize_by_amount(amount)
|
1473
|
+
# This also enables you to initialize a record if it is not found, such as find_or_initialize_by_amount(amount)
|
1401
1474
|
# or find_or_create_by_user_and_password(user, password).
|
1402
1475
|
#
|
1403
1476
|
# Each dynamic finder or initializer/creator is also defined in the class after it is first invoked, so that future
|
@@ -1410,7 +1483,7 @@ module ActiveRecord #:nodoc:
|
|
1410
1483
|
super unless all_attributes_exists?(attribute_names)
|
1411
1484
|
|
1412
1485
|
self.class_eval %{
|
1413
|
-
def self.#{method_id}(*args)
|
1486
|
+
def self.#{method_id}(*args)
|
1414
1487
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
1415
1488
|
attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
|
1416
1489
|
finder_options = { :conditions => attributes }
|
@@ -1433,24 +1506,24 @@ module ActiveRecord #:nodoc:
|
|
1433
1506
|
super unless all_attributes_exists?(attribute_names)
|
1434
1507
|
|
1435
1508
|
self.class_eval %{
|
1436
|
-
def self.#{method_id}(*args)
|
1509
|
+
def self.#{method_id}(*args)
|
1437
1510
|
if args[0].is_a?(Hash)
|
1438
1511
|
attributes = args[0].with_indifferent_access
|
1439
1512
|
find_attributes = attributes.slice(*[:#{attribute_names.join(',:')}])
|
1440
1513
|
else
|
1441
1514
|
find_attributes = attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
|
1442
1515
|
end
|
1443
|
-
|
1516
|
+
|
1444
1517
|
options = { :conditions => find_attributes }
|
1445
1518
|
set_readonly_option!(options)
|
1446
1519
|
|
1447
1520
|
record = find_initial(options)
|
1448
1521
|
if record.nil?
|
1449
|
-
record = self.new { |r| r.send(:attributes=, attributes, false) }
|
1522
|
+
record = self.new { |r| r.send(:attributes=, attributes, false) }
|
1450
1523
|
#{'record.save' if instantiator == :create}
|
1451
1524
|
record
|
1452
1525
|
else
|
1453
|
-
record
|
1526
|
+
record
|
1454
1527
|
end
|
1455
1528
|
end
|
1456
1529
|
}, __FILE__, __LINE__
|
@@ -1480,7 +1553,7 @@ module ActiveRecord #:nodoc:
|
|
1480
1553
|
|
1481
1554
|
def all_attributes_exists?(attribute_names)
|
1482
1555
|
attribute_names.all? { |name| column_methods_hash.include?(name.to_sym) }
|
1483
|
-
end
|
1556
|
+
end
|
1484
1557
|
|
1485
1558
|
def attribute_condition(argument)
|
1486
1559
|
case argument
|
@@ -1651,18 +1724,18 @@ module ActiveRecord #:nodoc:
|
|
1651
1724
|
scoped_methods = (Thread.current[:scoped_methods] ||= {})
|
1652
1725
|
scoped_methods[self] ||= []
|
1653
1726
|
end
|
1654
|
-
|
1727
|
+
|
1655
1728
|
def single_threaded_scoped_methods #:nodoc:
|
1656
1729
|
@scoped_methods ||= []
|
1657
1730
|
end
|
1658
|
-
|
1731
|
+
|
1659
1732
|
# pick up the correct scoped_methods version from @@allow_concurrency
|
1660
1733
|
if @@allow_concurrency
|
1661
1734
|
alias_method :scoped_methods, :thread_safe_scoped_methods
|
1662
1735
|
else
|
1663
1736
|
alias_method :scoped_methods, :single_threaded_scoped_methods
|
1664
1737
|
end
|
1665
|
-
|
1738
|
+
|
1666
1739
|
def current_scoped_methods #:nodoc:
|
1667
1740
|
scoped_methods.last
|
1668
1741
|
end
|
@@ -1835,8 +1908,8 @@ module ActiveRecord #:nodoc:
|
|
1835
1908
|
|
1836
1909
|
def encode_quoted_value(value) #:nodoc:
|
1837
1910
|
quoted_value = connection.quote(value)
|
1838
|
-
quoted_value = "'#{quoted_value[1..-2].gsub(/\'/, "\\\\'")}'" if quoted_value.include?("\\\'") # (for ruby mode) "
|
1839
|
-
quoted_value
|
1911
|
+
quoted_value = "'#{quoted_value[1..-2].gsub(/\'/, "\\\\'")}'" if quoted_value.include?("\\\'") # (for ruby mode) "
|
1912
|
+
quoted_value
|
1840
1913
|
end
|
1841
1914
|
end
|
1842
1915
|
|
@@ -1862,7 +1935,7 @@ module ActiveRecord #:nodoc:
|
|
1862
1935
|
def id
|
1863
1936
|
attr_name = self.class.primary_key
|
1864
1937
|
column = column_for_attribute(attr_name)
|
1865
|
-
|
1938
|
+
|
1866
1939
|
self.class.send(:define_read_method, :id, attr_name, column)
|
1867
1940
|
# now that the method exists, call it
|
1868
1941
|
self.send attr_name.to_sym
|
@@ -1898,8 +1971,8 @@ module ActiveRecord #:nodoc:
|
|
1898
1971
|
def save
|
1899
1972
|
create_or_update
|
1900
1973
|
end
|
1901
|
-
|
1902
|
-
# Attempts to save the record, but instead of just returning false if it couldn't happen, it raises a
|
1974
|
+
|
1975
|
+
# Attempts to save the record, but instead of just returning false if it couldn't happen, it raises a
|
1903
1976
|
# RecordNotSaved exception
|
1904
1977
|
def save!
|
1905
1978
|
create_or_update || raise(RecordNotSaved)
|
@@ -1960,7 +2033,7 @@ module ActiveRecord #:nodoc:
|
|
1960
2033
|
self.attributes = attributes
|
1961
2034
|
save
|
1962
2035
|
end
|
1963
|
-
|
2036
|
+
|
1964
2037
|
# Updates an object just like Base.update_attributes but calls save! instead of save so an exception is raised if the record is invalid.
|
1965
2038
|
def update_attributes!(attributes)
|
1966
2039
|
self.attributes = attributes
|
@@ -2031,7 +2104,7 @@ module ActiveRecord #:nodoc:
|
|
2031
2104
|
# matching the attribute names (which again matches the column names). Sensitive attributes can be protected
|
2032
2105
|
# from this form of mass-assignment by using the +attr_protected+ macro. Or you can alternatively
|
2033
2106
|
# specify which attributes *can* be accessed with the +attr_accessible+ macro. Then all the
|
2034
|
-
# attributes not included in that won't be allowed to be mass-assigned.
|
2107
|
+
# attributes not included in that won't be allowed to be mass-assigned.
|
2035
2108
|
def attributes=(new_attributes, guard_protected_attributes = true)
|
2036
2109
|
return if new_attributes.nil?
|
2037
2110
|
attributes = new_attributes.dup
|
@@ -2039,7 +2112,7 @@ module ActiveRecord #:nodoc:
|
|
2039
2112
|
|
2040
2113
|
multi_parameter_attributes = []
|
2041
2114
|
attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes
|
2042
|
-
|
2115
|
+
|
2043
2116
|
attributes.each do |k, v|
|
2044
2117
|
k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v)
|
2045
2118
|
end
|
@@ -2051,7 +2124,7 @@ module ActiveRecord #:nodoc:
|
|
2051
2124
|
# Returns a hash of all the attributes with their names as keys and clones of their objects as values.
|
2052
2125
|
def attributes(options = nil)
|
2053
2126
|
attributes = clone_attributes :read_attribute
|
2054
|
-
|
2127
|
+
|
2055
2128
|
if options.nil?
|
2056
2129
|
attributes
|
2057
2130
|
else
|
@@ -2112,8 +2185,8 @@ module ActiveRecord #:nodoc:
|
|
2112
2185
|
# Returns true if the +comparison_object+ is the same object, or is of the same type and has the same id.
|
2113
2186
|
def ==(comparison_object)
|
2114
2187
|
comparison_object.equal?(self) ||
|
2115
|
-
(comparison_object.instance_of?(self.class) &&
|
2116
|
-
comparison_object.id == id &&
|
2188
|
+
(comparison_object.instance_of?(self.class) &&
|
2189
|
+
comparison_object.id == id &&
|
2117
2190
|
!comparison_object.new_record?)
|
2118
2191
|
end
|
2119
2192
|
|