activerecord 4.0.4 → 4.1.16

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.

Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1632 -1797
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/examples/performance.rb +30 -18
  6. data/examples/simple.rb +4 -4
  7. data/lib/active_record/aggregations.rb +2 -1
  8. data/lib/active_record/association_relation.rb +4 -0
  9. data/lib/active_record/associations/alias_tracker.rb +49 -29
  10. data/lib/active_record/associations/association.rb +9 -17
  11. data/lib/active_record/associations/association_scope.rb +59 -49
  12. data/lib/active_record/associations/belongs_to_association.rb +34 -25
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +6 -1
  14. data/lib/active_record/associations/builder/association.rb +84 -54
  15. data/lib/active_record/associations/builder/belongs_to.rb +90 -58
  16. data/lib/active_record/associations/builder/collection_association.rb +47 -45
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +119 -25
  18. data/lib/active_record/associations/builder/has_many.rb +3 -3
  19. data/lib/active_record/associations/builder/has_one.rb +5 -7
  20. data/lib/active_record/associations/builder/singular_association.rb +6 -7
  21. data/lib/active_record/associations/collection_association.rb +121 -111
  22. data/lib/active_record/associations/collection_proxy.rb +73 -18
  23. data/lib/active_record/associations/has_many_association.rb +14 -11
  24. data/lib/active_record/associations/has_many_through_association.rb +33 -6
  25. data/lib/active_record/associations/has_one_association.rb +1 -1
  26. data/lib/active_record/associations/join_dependency/join_association.rb +46 -104
  27. data/lib/active_record/associations/join_dependency/join_base.rb +6 -8
  28. data/lib/active_record/associations/join_dependency/join_part.rb +18 -37
  29. data/lib/active_record/associations/join_dependency.rb +208 -168
  30. data/lib/active_record/associations/preloader/association.rb +69 -27
  31. data/lib/active_record/associations/preloader/collection_association.rb +2 -2
  32. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  33. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  34. data/lib/active_record/associations/preloader/through_association.rb +58 -26
  35. data/lib/active_record/associations/preloader.rb +63 -49
  36. data/lib/active_record/associations/singular_association.rb +6 -5
  37. data/lib/active_record/associations/through_association.rb +30 -9
  38. data/lib/active_record/associations.rb +116 -42
  39. data/lib/active_record/attribute_assignment.rb +6 -3
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -1
  41. data/lib/active_record/attribute_methods/dirty.rb +35 -26
  42. data/lib/active_record/attribute_methods/primary_key.rb +8 -1
  43. data/lib/active_record/attribute_methods/read.rb +56 -29
  44. data/lib/active_record/attribute_methods/serialization.rb +44 -12
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +13 -1
  46. data/lib/active_record/attribute_methods/write.rb +59 -26
  47. data/lib/active_record/attribute_methods.rb +82 -43
  48. data/lib/active_record/autosave_association.rb +209 -194
  49. data/lib/active_record/base.rb +6 -2
  50. data/lib/active_record/callbacks.rb +2 -2
  51. data/lib/active_record/coders/json.rb +13 -0
  52. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +5 -10
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +14 -24
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -13
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +6 -3
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +90 -0
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -8
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +45 -70
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -0
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -96
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +74 -66
  63. data/lib/active_record/connection_adapters/column.rb +1 -35
  64. data/lib/active_record/connection_adapters/connection_specification.rb +231 -43
  65. data/lib/active_record/connection_adapters/mysql2_adapter.rb +10 -5
  66. data/lib/active_record/connection_adapters/mysql_adapter.rb +24 -17
  67. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +22 -15
  68. data/lib/active_record/connection_adapters/postgresql/cast.rb +12 -4
  69. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -44
  70. data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -14
  71. data/lib/active_record/connection_adapters/postgresql/quoting.rb +37 -12
  72. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +20 -11
  73. data/lib/active_record/connection_adapters/postgresql_adapter.rb +98 -52
  74. data/lib/active_record/connection_adapters/schema_cache.rb +8 -29
  75. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -60
  76. data/lib/active_record/connection_handling.rb +39 -5
  77. data/lib/active_record/core.rb +38 -54
  78. data/lib/active_record/counter_cache.rb +9 -10
  79. data/lib/active_record/dynamic_matchers.rb +6 -2
  80. data/lib/active_record/enum.rb +199 -0
  81. data/lib/active_record/errors.rb +22 -5
  82. data/lib/active_record/fixture_set/file.rb +2 -1
  83. data/lib/active_record/fixtures.rb +173 -76
  84. data/lib/active_record/gem_version.rb +15 -0
  85. data/lib/active_record/inheritance.rb +23 -9
  86. data/lib/active_record/integration.rb +54 -1
  87. data/lib/active_record/locking/optimistic.rb +7 -2
  88. data/lib/active_record/locking/pessimistic.rb +1 -1
  89. data/lib/active_record/log_subscriber.rb +6 -13
  90. data/lib/active_record/migration/command_recorder.rb +8 -2
  91. data/lib/active_record/migration.rb +91 -56
  92. data/lib/active_record/model_schema.rb +7 -14
  93. data/lib/active_record/nested_attributes.rb +25 -13
  94. data/lib/active_record/no_touching.rb +52 -0
  95. data/lib/active_record/null_relation.rb +26 -6
  96. data/lib/active_record/persistence.rb +23 -29
  97. data/lib/active_record/querying.rb +15 -12
  98. data/lib/active_record/railtie.rb +12 -61
  99. data/lib/active_record/railties/databases.rake +37 -56
  100. data/lib/active_record/readonly_attributes.rb +0 -6
  101. data/lib/active_record/reflection.rb +230 -79
  102. data/lib/active_record/relation/batches.rb +74 -24
  103. data/lib/active_record/relation/calculations.rb +52 -48
  104. data/lib/active_record/relation/delegation.rb +54 -39
  105. data/lib/active_record/relation/finder_methods.rb +210 -67
  106. data/lib/active_record/relation/merger.rb +15 -12
  107. data/lib/active_record/relation/predicate_builder/array_handler.rb +29 -0
  108. data/lib/active_record/relation/predicate_builder/relation_handler.rb +17 -0
  109. data/lib/active_record/relation/predicate_builder.rb +81 -40
  110. data/lib/active_record/relation/query_methods.rb +185 -108
  111. data/lib/active_record/relation/spawn_methods.rb +8 -5
  112. data/lib/active_record/relation.rb +79 -84
  113. data/lib/active_record/result.rb +45 -6
  114. data/lib/active_record/runtime_registry.rb +5 -0
  115. data/lib/active_record/sanitization.rb +4 -4
  116. data/lib/active_record/schema_dumper.rb +18 -6
  117. data/lib/active_record/schema_migration.rb +31 -18
  118. data/lib/active_record/scoping/default.rb +5 -18
  119. data/lib/active_record/scoping/named.rb +14 -29
  120. data/lib/active_record/scoping.rb +5 -0
  121. data/lib/active_record/store.rb +67 -18
  122. data/lib/active_record/tasks/database_tasks.rb +66 -26
  123. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -10
  124. data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
  125. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  126. data/lib/active_record/timestamp.rb +6 -6
  127. data/lib/active_record/transactions.rb +10 -12
  128. data/lib/active_record/validations/presence.rb +1 -1
  129. data/lib/active_record/validations/uniqueness.rb +19 -9
  130. data/lib/active_record/version.rb +4 -7
  131. data/lib/active_record.rb +5 -7
  132. data/lib/rails/generators/active_record/migration/migration_generator.rb +4 -0
  133. data/lib/rails/generators/active_record/migration.rb +18 -0
  134. data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
  135. data/lib/rails/generators/active_record.rb +2 -8
  136. metadata +18 -30
  137. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -65
  138. data/lib/active_record/associations/join_helper.rb +0 -45
  139. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  140. data/lib/active_record/tasks/firebird_database_tasks.rb +0 -56
  141. data/lib/active_record/tasks/oracle_database_tasks.rb +0 -45
  142. data/lib/active_record/tasks/sqlserver_database_tasks.rb +0 -48
  143. data/lib/active_record/test_case.rb +0 -96
@@ -35,7 +35,7 @@ module ActiveRecord
35
35
  #
36
36
  # === One-to-one Example
37
37
  #
38
- # class Post
38
+ # class Post < ActiveRecord::Base
39
39
  # has_one :author, autosave: true
40
40
  # end
41
41
  #
@@ -76,7 +76,7 @@ module ActiveRecord
76
76
  #
77
77
  # When <tt>:autosave</tt> is not declared new children are saved when their parent is saved:
78
78
  #
79
- # class Post
79
+ # class Post < ActiveRecord::Base
80
80
  # has_many :comments # :autosave option is not declared
81
81
  # end
82
82
  #
@@ -95,20 +95,23 @@ module ActiveRecord
95
95
  # When <tt>:autosave</tt> is true all children are saved, no matter whether they
96
96
  # are new records or not:
97
97
  #
98
- # class Post
98
+ # class Post < ActiveRecord::Base
99
99
  # has_many :comments, autosave: true
100
100
  # end
101
101
  #
102
102
  # post = Post.create(title: 'ruby rocks')
103
103
  # post.comments.create(body: 'hello world')
104
104
  # post.comments[0].body = 'hi everyone'
105
- # post.save # => saves both post and comment, with 'hi everyone' as body
105
+ # post.comments.build(body: "good morning.")
106
+ # post.title += "!"
107
+ # post.save # => saves both post and comments.
106
108
  #
107
109
  # Destroying one of the associated models as part of the parent's save action
108
110
  # is as simple as marking it for destruction:
109
111
  #
110
- # post.comments.last.mark_for_destruction
111
- # post.comments.last.marked_for_destruction? # => true
112
+ # post.comments # => [#<Comment id: 1, ...>, #<Comment id: 2, ...]>
113
+ # post.comments[1].mark_for_destruction
114
+ # post.comments[1].marked_for_destruction? # => true
112
115
  # post.comments.length # => 2
113
116
  #
114
117
  # Note that the model is _not_ yet removed from the database:
@@ -127,65 +130,63 @@ module ActiveRecord
127
130
  extend ActiveSupport::Concern
128
131
 
129
132
  module AssociationBuilderExtension #:nodoc:
130
- def build
133
+ def self.build(model, reflection)
131
134
  model.send(:add_autosave_association_callbacks, reflection)
132
- super
135
+ end
136
+
137
+ def self.valid_options
138
+ [ :autosave ]
133
139
  end
134
140
  end
135
141
 
136
142
  included do
137
- Associations::Builder::Association.class_eval do
138
- self.valid_options << :autosave
139
- include AssociationBuilderExtension
140
- end
143
+ Associations::Builder::Association.extensions << AssociationBuilderExtension
141
144
  end
142
145
 
143
146
  module ClassMethods
144
147
  private
145
148
 
146
- def define_non_cyclic_method(name, reflection, &block)
147
- define_method(name) do |*args|
148
- result = true; @_already_called ||= {}
149
- # Loop prevention for validation of associations
150
- unless @_already_called[[name, reflection.name]]
151
- begin
152
- @_already_called[[name, reflection.name]]=true
153
- result = instance_eval(&block)
154
- ensure
155
- @_already_called[[name, reflection.name]]=false
149
+ def define_non_cyclic_method(name, &block)
150
+ return if method_defined?(name)
151
+ define_method(name) do |*args|
152
+ result = true; @_already_called ||= {}
153
+ # Loop prevention for validation of associations
154
+ unless @_already_called[name]
155
+ begin
156
+ @_already_called[name]=true
157
+ result = instance_eval(&block)
158
+ ensure
159
+ @_already_called[name]=false
160
+ end
156
161
  end
157
- end
158
162
 
159
- result
163
+ result
164
+ end
160
165
  end
161
- end
162
166
 
163
- # Adds validation and save callbacks for the association as specified by
164
- # the +reflection+.
165
- #
166
- # For performance reasons, we don't check whether to validate at runtime.
167
- # However the validation and callback methods are lazy and those methods
168
- # get created when they are invoked for the very first time. However,
169
- # this can change, for instance, when using nested attributes, which is
170
- # called _after_ the association has been defined. Since we don't want
171
- # the callbacks to get defined multiple times, there are guards that
172
- # check if the save or validation methods have already been defined
173
- # before actually defining them.
174
- def add_autosave_association_callbacks(reflection)
175
- save_method = :"autosave_associated_records_for_#{reflection.name}"
176
- validation_method = :"validate_associated_records_for_#{reflection.name}"
177
- collection = reflection.collection?
178
-
179
- unless method_defined?(save_method)
180
- if collection
167
+ # Adds validation and save callbacks for the association as specified by
168
+ # the +reflection+.
169
+ #
170
+ # For performance reasons, we don't check whether to validate at runtime.
171
+ # However the validation and callback methods are lazy and those methods
172
+ # get created when they are invoked for the very first time. However,
173
+ # this can change, for instance, when using nested attributes, which is
174
+ # called _after_ the association has been defined. Since we don't want
175
+ # the callbacks to get defined multiple times, there are guards that
176
+ # check if the save or validation methods have already been defined
177
+ # before actually defining them.
178
+ def add_autosave_association_callbacks(reflection)
179
+ save_method = :"autosave_associated_records_for_#{reflection.name}"
180
+
181
+ if reflection.collection?
181
182
  before_save :before_save_collection_association
182
183
 
183
- define_non_cyclic_method(save_method, reflection) { save_collection_association(reflection) }
184
+ define_non_cyclic_method(save_method) { save_collection_association(reflection) }
184
185
  # Doesn't use after_save as that would save associations added in after_create/after_update twice
185
186
  after_create save_method
186
187
  after_update save_method
187
188
  elsif reflection.macro == :has_one
188
- define_method(save_method) { save_has_one_association(reflection) }
189
+ define_method(save_method) { save_has_one_association(reflection) } unless method_defined?(save_method)
189
190
  # Configures two callbacks instead of a single after_save so that
190
191
  # the model may rely on their execution order relative to its
191
192
  # own callbacks.
@@ -197,17 +198,29 @@ module ActiveRecord
197
198
  after_create save_method
198
199
  after_update save_method
199
200
  else
200
- define_non_cyclic_method(save_method, reflection) { save_belongs_to_association(reflection) }
201
+ define_non_cyclic_method(save_method) { save_belongs_to_association(reflection) }
201
202
  before_save save_method
202
203
  end
204
+
205
+ define_autosave_validation_callbacks(reflection)
203
206
  end
204
207
 
205
- if reflection.validate? && !method_defined?(validation_method)
206
- method = (collection ? :validate_collection_association : :validate_single_association)
207
- define_non_cyclic_method(validation_method, reflection) { send(method, reflection) }
208
- validate validation_method
208
+ def define_autosave_validation_callbacks(reflection)
209
+ validation_method = :"validate_associated_records_for_#{reflection.name}"
210
+ if reflection.validate? && !method_defined?(validation_method)
211
+ if reflection.collection?
212
+ method = :validate_collection_association
213
+ else
214
+ method = :validate_single_association
215
+ end
216
+
217
+ define_non_cyclic_method(validation_method) do
218
+ send(method, reflection)
219
+ true
220
+ end
221
+ validate validation_method
222
+ end
209
223
  end
210
- end
211
224
  end
212
225
 
213
226
  # Reloads the attributes of the object as usual and clears <tt>marked_for_destruction</tt> flag.
@@ -254,179 +267,181 @@ module ActiveRecord
254
267
 
255
268
  private
256
269
 
257
- # Returns the record for an association collection that should be validated
258
- # or saved. If +autosave+ is +false+ only new records will be returned,
259
- # unless the parent is/was a new record itself.
260
- def associated_records_to_validate_or_save(association, new_record, autosave)
261
- if new_record
262
- association && association.target
263
- elsif autosave
264
- association.target.find_all { |record| record.changed_for_autosave? }
265
- else
266
- association.target.find_all { |record| record.new_record? }
270
+ # Returns the record for an association collection that should be validated
271
+ # or saved. If +autosave+ is +false+ only new records will be returned,
272
+ # unless the parent is/was a new record itself.
273
+ def associated_records_to_validate_or_save(association, new_record, autosave)
274
+ if new_record
275
+ association && association.target
276
+ elsif autosave
277
+ association.target.find_all { |record| record.changed_for_autosave? }
278
+ else
279
+ association.target.find_all { |record| record.new_record? }
280
+ end
281
+ end
282
+
283
+ # go through nested autosave associations that are loaded in memory (without loading
284
+ # any new ones), and return true if is changed for autosave
285
+ def nested_records_changed_for_autosave?
286
+ self.class._reflections.values.any? do |reflection|
287
+ if reflection.options[:autosave]
288
+ association = association_instance_get(reflection.name)
289
+ association && Array.wrap(association.target).any? { |a| a.changed_for_autosave? }
290
+ end
291
+ end
267
292
  end
268
- end
269
293
 
270
- # go through nested autosave associations that are loaded in memory (without loading
271
- # any new ones), and return true if is changed for autosave
272
- def nested_records_changed_for_autosave?
273
- self.class.reflect_on_all_autosave_associations.any? do |reflection|
294
+ # Validate the association if <tt>:validate</tt> or <tt>:autosave</tt> is
295
+ # turned on for the association.
296
+ def validate_single_association(reflection)
274
297
  association = association_instance_get(reflection.name)
275
- association && Array.wrap(association.target).any? { |a| a.changed_for_autosave? }
298
+ record = association && association.reader
299
+ association_valid?(reflection, record) if record
276
300
  end
277
- end
278
-
279
- # Validate the association if <tt>:validate</tt> or <tt>:autosave</tt> is
280
- # turned on for the association.
281
- def validate_single_association(reflection)
282
- association = association_instance_get(reflection.name)
283
- record = association && association.reader
284
- association_valid?(reflection, record) if record
285
- end
286
301
 
287
- # Validate the associated records if <tt>:validate</tt> or
288
- # <tt>:autosave</tt> is turned on for the association specified by
289
- # +reflection+.
290
- def validate_collection_association(reflection)
291
- if association = association_instance_get(reflection.name)
292
- if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
293
- records.each { |record| association_valid?(reflection, record) }
302
+ # Validate the associated records if <tt>:validate</tt> or
303
+ # <tt>:autosave</tt> is turned on for the association specified by
304
+ # +reflection+.
305
+ def validate_collection_association(reflection)
306
+ if association = association_instance_get(reflection.name)
307
+ if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
308
+ records.each { |record| association_valid?(reflection, record) }
309
+ end
294
310
  end
295
311
  end
296
- end
297
312
 
298
- # Returns whether or not the association is valid and applies any errors to
299
- # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
300
- # enabled records if they're marked_for_destruction? or destroyed.
301
- def association_valid?(reflection, record)
302
- return true if record.destroyed? || record.marked_for_destruction?
303
-
304
- unless valid = record.valid?
305
- if reflection.options[:autosave]
306
- record.errors.each do |attribute, message|
307
- attribute = "#{reflection.name}.#{attribute}"
308
- errors[attribute] << message
309
- errors[attribute].uniq!
313
+ # Returns whether or not the association is valid and applies any errors to
314
+ # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
315
+ # enabled records if they're marked_for_destruction? or destroyed.
316
+ def association_valid?(reflection, record)
317
+ return true if record.destroyed? || record.marked_for_destruction?
318
+
319
+ unless valid = record.valid?
320
+ if reflection.options[:autosave]
321
+ record.errors.each do |attribute, message|
322
+ attribute = "#{reflection.name}.#{attribute}"
323
+ errors[attribute] << message
324
+ errors[attribute].uniq!
325
+ end
326
+ else
327
+ errors.add(reflection.name)
310
328
  end
311
- else
312
- errors.add(reflection.name)
313
329
  end
330
+ valid
314
331
  end
315
- valid
316
- end
317
332
 
318
- # Is used as a before_save callback to check while saving a collection
319
- # association whether or not the parent was a new record before saving.
320
- def before_save_collection_association
321
- @new_record_before_save = new_record?
322
- true
323
- end
333
+ # Is used as a before_save callback to check while saving a collection
334
+ # association whether or not the parent was a new record before saving.
335
+ def before_save_collection_association
336
+ @new_record_before_save = new_record?
337
+ true
338
+ end
324
339
 
325
- # Saves any new associated records, or all loaded autosave associations if
326
- # <tt>:autosave</tt> is enabled on the association.
327
- #
328
- # In addition, it destroys all children that were marked for destruction
329
- # with mark_for_destruction.
330
- #
331
- # This all happens inside a transaction, _if_ the Transactions module is included into
332
- # ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
333
- def save_collection_association(reflection)
334
- if association = association_instance_get(reflection.name)
335
- autosave = reflection.options[:autosave]
336
-
337
- if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
338
-
339
- if autosave
340
- records_to_destroy = records.select(&:marked_for_destruction?)
341
- records_to_destroy.each { |record| association.destroy(record) }
342
- records -= records_to_destroy
343
- end
340
+ # Saves any new associated records, or all loaded autosave associations if
341
+ # <tt>:autosave</tt> is enabled on the association.
342
+ #
343
+ # In addition, it destroys all children that were marked for destruction
344
+ # with mark_for_destruction.
345
+ #
346
+ # This all happens inside a transaction, _if_ the Transactions module is included into
347
+ # ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
348
+ def save_collection_association(reflection)
349
+ if association = association_instance_get(reflection.name)
350
+ autosave = reflection.options[:autosave]
351
+
352
+ if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
353
+ if autosave
354
+ records_to_destroy = records.select(&:marked_for_destruction?)
355
+ records_to_destroy.each { |record| association.destroy(record) }
356
+ records -= records_to_destroy
357
+ end
344
358
 
345
- records.each do |record|
346
- next if record.destroyed?
359
+ records.each do |record|
360
+ next if record.destroyed?
347
361
 
348
- saved = true
362
+ saved = true
349
363
 
350
- if autosave != false && (@new_record_before_save || record.new_record?)
351
- if autosave
352
- saved = association.insert_record(record, false)
353
- else
354
- association.insert_record(record) unless reflection.nested?
364
+ if autosave != false && (@new_record_before_save || record.new_record?)
365
+ if autosave
366
+ saved = association.insert_record(record, false)
367
+ else
368
+ association.insert_record(record) unless reflection.nested?
369
+ end
370
+ elsif autosave
371
+ saved = record.save(:validate => false)
355
372
  end
356
- elsif autosave
357
- saved = record.save(:validate => false)
358
- end
359
373
 
360
- raise ActiveRecord::Rollback unless saved
374
+ raise ActiveRecord::Rollback unless saved
375
+ end
361
376
  end
362
- end
363
377
 
364
- # reconstruct the scope now that we know the owner's id
365
- association.reset_scope if association.respond_to?(:reset_scope)
378
+ # reconstruct the scope now that we know the owner's id
379
+ association.reset_scope if association.respond_to?(:reset_scope)
380
+ end
366
381
  end
367
- end
368
382
 
369
- # Saves the associated record if it's new or <tt>:autosave</tt> is enabled
370
- # on the association.
371
- #
372
- # In addition, it will destroy the association if it was marked for
373
- # destruction with mark_for_destruction.
374
- #
375
- # This all happens inside a transaction, _if_ the Transactions module is included into
376
- # ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
377
- def save_has_one_association(reflection)
378
- association = association_instance_get(reflection.name)
379
- record = association && association.load_target
380
- if record && !record.destroyed?
381
- autosave = reflection.options[:autosave]
382
-
383
- if autosave && record.marked_for_destruction?
384
- record.destroy
385
- elsif autosave != false
386
- key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
387
-
388
- if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
389
- unless reflection.through_reflection
390
- record[reflection.foreign_key] = key
391
- end
383
+ # Saves the associated record if it's new or <tt>:autosave</tt> is enabled
384
+ # on the association.
385
+ #
386
+ # In addition, it will destroy the association if it was marked for
387
+ # destruction with mark_for_destruction.
388
+ #
389
+ # This all happens inside a transaction, _if_ the Transactions module is included into
390
+ # ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
391
+ def save_has_one_association(reflection)
392
+ association = association_instance_get(reflection.name)
393
+ record = association && association.load_target
394
+
395
+ if record && !record.destroyed?
396
+ autosave = reflection.options[:autosave]
397
+
398
+ if autosave && record.marked_for_destruction?
399
+ record.destroy
400
+ elsif autosave != false
401
+ key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
402
+
403
+ if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
404
+ unless reflection.through_reflection
405
+ record[reflection.foreign_key] = key
406
+ end
392
407
 
393
- saved = record.save(:validate => !autosave)
394
- raise ActiveRecord::Rollback if !saved && autosave
395
- saved
408
+ saved = record.save(:validate => !autosave)
409
+ raise ActiveRecord::Rollback if !saved && autosave
410
+ saved
411
+ end
396
412
  end
397
413
  end
398
414
  end
399
- end
400
415
 
401
- # If the record is new or it has changed, returns true.
402
- def record_changed?(reflection, record, key)
403
- record.new_record? || record[reflection.foreign_key] != key || record.changed_attributes.include?(reflection.foreign_key)
404
- end
416
+ # If the record is new or it has changed, returns true.
417
+ def record_changed?(reflection, record, key)
418
+ record.new_record? || record[reflection.foreign_key] != key || record.attribute_changed?(reflection.foreign_key)
419
+ end
405
420
 
406
- # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
407
- #
408
- # In addition, it will destroy the association if it was marked for destruction.
409
- def save_belongs_to_association(reflection)
410
- association = association_instance_get(reflection.name)
411
- record = association && association.load_target
412
- if record && !record.destroyed?
413
- autosave = reflection.options[:autosave]
414
-
415
- if autosave && record.marked_for_destruction?
416
- self[reflection.foreign_key] = nil
417
- record.destroy
418
- elsif autosave != false
419
- saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
420
-
421
- if association.updated?
422
- association_id = record.send(reflection.options[:primary_key] || :id)
423
- self[reflection.foreign_key] = association_id
424
- association.loaded!
425
- end
421
+ # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
422
+ #
423
+ # In addition, it will destroy the association if it was marked for destruction.
424
+ def save_belongs_to_association(reflection)
425
+ association = association_instance_get(reflection.name)
426
+ record = association && association.load_target
427
+ if record && !record.destroyed?
428
+ autosave = reflection.options[:autosave]
429
+
430
+ if autosave && record.marked_for_destruction?
431
+ self[reflection.foreign_key] = nil
432
+ record.destroy
433
+ elsif autosave != false
434
+ saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
435
+
436
+ if association.updated?
437
+ association_id = record.send(reflection.options[:primary_key] || :id)
438
+ self[reflection.foreign_key] = association_id
439
+ association.loaded!
440
+ end
426
441
 
427
- saved if autosave
442
+ saved if autosave
443
+ end
428
444
  end
429
445
  end
430
- end
431
446
  end
432
447
  end
@@ -4,7 +4,7 @@ require 'active_support/benchmarkable'
4
4
  require 'active_support/dependencies'
5
5
  require 'active_support/descendants_tracker'
6
6
  require 'active_support/time'
7
- require 'active_support/core_ext/class/attribute_accessors'
7
+ require 'active_support/core_ext/module/attribute_accessors'
8
8
  require 'active_support/core_ext/class/delegating_attributes'
9
9
  require 'active_support/core_ext/array/extract_options'
10
10
  require 'active_support/core_ext/hash/deep_merge'
@@ -18,6 +18,7 @@ require 'arel'
18
18
  require 'active_record/errors'
19
19
  require 'active_record/log_subscriber'
20
20
  require 'active_record/explain_subscriber'
21
+ require 'active_record/relation/delegation'
21
22
 
22
23
  module ActiveRecord #:nodoc:
23
24
  # = Active Record
@@ -290,7 +291,10 @@ module ActiveRecord #:nodoc:
290
291
  extend Translation
291
292
  extend DynamicMatchers
292
293
  extend Explain
294
+ extend Enum
295
+ extend Delegation::DelegateCache
293
296
 
297
+ include Core
294
298
  include Persistence
295
299
  include ReadonlyAttributes
296
300
  include ModelSchema
@@ -313,10 +317,10 @@ module ActiveRecord #:nodoc:
313
317
  include NestedAttributes
314
318
  include Aggregations
315
319
  include Transactions
320
+ include NoTouching
316
321
  include Reflection
317
322
  include Serialization
318
323
  include Store
319
- include Core
320
324
  end
321
325
 
322
326
  ActiveSupport.run_load_hooks(:active_record, Base)
@@ -302,11 +302,11 @@ module ActiveRecord
302
302
  run_callbacks(:save) { super }
303
303
  end
304
304
 
305
- def create_record #:nodoc:
305
+ def _create_record #:nodoc:
306
306
  run_callbacks(:create) { super }
307
307
  end
308
308
 
309
- def update_record(*) #:nodoc:
309
+ def _update_record(*) #:nodoc:
310
310
  run_callbacks(:update) { super }
311
311
  end
312
312
  end
@@ -0,0 +1,13 @@
1
+ module ActiveRecord
2
+ module Coders # :nodoc:
3
+ class JSON # :nodoc:
4
+ def self.dump(obj)
5
+ ActiveSupport::JSON.encode(obj)
6
+ end
7
+
8
+ def self.load(json)
9
+ ActiveSupport::JSON.decode(json) unless json.nil?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -86,7 +86,7 @@ module ActiveRecord
86
86
  end
87
87
  end
88
88
 
89
- # Return the number of threads currently waiting on this
89
+ # Returns the number of threads currently waiting on this
90
90
  # queue.
91
91
  def num_waiting
92
92
  synchronize do
@@ -236,9 +236,9 @@ module ActiveRecord
236
236
 
237
237
  @spec = spec
238
238
 
239
- @checkout_timeout = spec.config[:checkout_timeout] || 5
240
- @dead_connection_timeout = spec.config[:dead_connection_timeout] || 5
241
- @reaper = Reaper.new self, spec.config[:reaping_frequency]
239
+ @checkout_timeout = (spec.config[:checkout_timeout] && spec.config[:checkout_timeout].to_f) || 5
240
+ @dead_connection_timeout = (spec.config[:dead_connection_timeout] && spec.config[:dead_connection_timeout].to_f) || 5
241
+ @reaper = Reaper.new(self, (spec.config[:reaping_frequency] && spec.config[:reaping_frequency].to_f))
242
242
  @reaper.run
243
243
 
244
244
  # default max pool size to 5
@@ -332,11 +332,6 @@ module ActiveRecord
332
332
  end
333
333
  end
334
334
 
335
- def clear_stale_cached_connections! # :nodoc:
336
- reap
337
- end
338
- deprecate :clear_stale_cached_connections! => "Please use #reap instead"
339
-
340
335
  # Check-out a database connection from the pool, indicating that you want
341
336
  # to use it. You should call #checkin when you no longer need this.
342
337
  #
@@ -629,7 +624,7 @@ module ActiveRecord
629
624
  end
630
625
 
631
626
  response
632
- rescue
627
+ rescue Exception
633
628
  ActiveRecord::Base.clear_active_connections! unless testing
634
629
  raise
635
630
  end