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 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 so newlines etc are escaped #10385 [norbert]
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 [chuyeow]
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 [lifofifo]
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. [tarmo, Koz]
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 [lifofifo]
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 [kamal]
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, josh]
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 [lifofifo, mortent]
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 [lifofifo]
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. [tarmo]
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 [tarmo]
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 [frederick.cheung@gmail.com]
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 #3998 [robbyrussell/tarmo]
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/chuyeow]
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 #9514 [lifofifo]
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 #9516 [josh]
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 [josh]
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 [lifo]
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 [lifofifo]
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 [lifofifo]
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 [lifofifo]
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 [lifofifo]
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 [lifofifo]
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 [lifofifo]
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 [kamal, theamazingrando]
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 [lifofifo, daxhuiberts]
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 #4276 [mrj/manfred/josh]
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 [kamal]
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 [kamal]
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, joshpeek, Rick]
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 [josh@joshpeek.com]. Examples:
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 [josh@joshpeek.com]. Examples:
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.1' + PKG_BUILD)
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] ? records.to_set.to_a : records
151
+ records.uniq! if @reflection.options[:uniq]
152
+ records
152
153
  end
153
154
 
154
155
  # Construct attributes for associate pointing to owner.
@@ -3,39 +3,98 @@ require 'yaml'
3
3
  require 'set'
4
4
 
5
5
  module ActiveRecord #:nodoc:
6
- class ActiveRecordError < StandardError #:nodoc:
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
- class AssociationTypeMismatch < ActiveRecordError #:nodoc:
11
- end
12
- class SerializationTypeMismatch < ActiveRecordError #:nodoc:
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
- class AdapterNotSpecified < ActiveRecordError # :nodoc:
33
+
34
+ # Raised when unserialized object's type mismatches one specified for serializable field.
35
+ class SerializationTypeMismatch < ActiveRecordError
15
36
  end
16
- class AdapterNotFound < ActiveRecordError # :nodoc:
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
- class ConnectionNotEstablished < ActiveRecordError #:nodoc:
41
+
42
+ # Raised when ActiveRecord cannot find database adapter specified in config/database.yml or programmatically.
43
+ class AdapterNotFound < ActiveRecordError
19
44
  end
20
- class ConnectionFailed < ActiveRecordError #:nodoc:
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
- class RecordNotFound < ActiveRecordError #:nodoc:
49
+
50
+ # Raised when ActiveRecord cannot find record by given id or set of ids.
51
+ class RecordNotFound < ActiveRecordError
23
52
  end
24
- class RecordNotSaved < ActiveRecordError #:nodoc:
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
- class StatementInvalid < ActiveRecordError #:nodoc:
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
- class PreparedStatementInvalid < ActiveRecordError #:nodoc:
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
- class StaleObjectError < ActiveRecordError #:nodoc:
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
- class ConfigurationError < ActiveRecordError #:nodoc:
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
- class ReadOnlyRecord < ActiveRecordError #:nodoc:
86
+
87
+ # Raised on attempt to update record that is instantiated as read only.
88
+ class ReadOnlyRecord < ActiveRecordError
35
89
  end
36
- class Rollback < ActiveRecordError #:nodoc:
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
- class DangerousAttributeError < ActiveRecordError #:nodoc:
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>: An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (Rarely needed).
391
- # Accepts named associations in the form of :include, which will perform an INNER JOIN on the associated table(s).
392
- # The records will be returned read-only since they will have attributes that do not correspond to the table's columns.
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 => "#{table_name}.#{primary_key}", :conditions => expand_id_conditions(id_or_conditions)).nil?
502
- rescue ActiveRecord::ActiveRecordError
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 objects for all the records that match the +conditions+ by instantiating each object and calling
630
- # the destroy method. Example:
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 all the records that match the +conditions+ without instantiating the objects first (and hence not
637
- # calling the destroy method). Example:
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