activerecord 5.0.7 → 5.1.7

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 (219) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +657 -2080
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record/aggregations.rb +244 -244
  8. data/lib/active_record/association_relation.rb +5 -5
  9. data/lib/active_record/associations/alias_tracker.rb +10 -11
  10. data/lib/active_record/associations/association.rb +23 -5
  11. data/lib/active_record/associations/association_scope.rb +95 -81
  12. data/lib/active_record/associations/belongs_to_association.rb +7 -4
  13. data/lib/active_record/associations/builder/belongs_to.rb +30 -16
  14. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  16. data/lib/active_record/associations/collection_association.rb +36 -205
  17. data/lib/active_record/associations/collection_proxy.rb +132 -63
  18. data/lib/active_record/associations/has_many_association.rb +10 -19
  19. data/lib/active_record/associations/has_many_through_association.rb +12 -4
  20. data/lib/active_record/associations/has_one_association.rb +24 -28
  21. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  22. data/lib/active_record/associations/join_dependency/join_association.rb +4 -28
  23. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  24. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  25. data/lib/active_record/associations/join_dependency.rb +121 -118
  26. data/lib/active_record/associations/preloader/association.rb +64 -64
  27. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  28. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  29. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  30. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  31. data/lib/active_record/associations/preloader/through_association.rb +41 -41
  32. data/lib/active_record/associations/preloader.rb +94 -94
  33. data/lib/active_record/associations/singular_association.rb +8 -25
  34. data/lib/active_record/associations/through_association.rb +2 -5
  35. data/lib/active_record/associations.rb +1591 -1562
  36. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute_assignment.rb +61 -61
  39. data/lib/active_record/attribute_decorators.rb +35 -13
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +229 -46
  42. data/lib/active_record/attribute_methods/primary_key.rb +74 -73
  43. data/lib/active_record/attribute_methods/read.rb +39 -35
  44. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  46. data/lib/active_record/attribute_methods/write.rb +30 -33
  47. data/lib/active_record/attribute_methods.rb +56 -65
  48. data/lib/active_record/attribute_mutation_tracker.rb +63 -11
  49. data/lib/active_record/attribute_set/builder.rb +27 -33
  50. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  51. data/lib/active_record/attribute_set.rb +9 -6
  52. data/lib/active_record/attributes.rb +22 -22
  53. data/lib/active_record/autosave_association.rb +18 -13
  54. data/lib/active_record/base.rb +24 -22
  55. data/lib/active_record/callbacks.rb +56 -14
  56. data/lib/active_record/coders/yaml_column.rb +9 -11
  57. data/lib/active_record/collection_cache_key.rb +3 -4
  58. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +330 -284
  59. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  60. data/lib/active_record/connection_adapters/abstract/database_statements.rb +39 -37
  61. data/lib/active_record/connection_adapters/abstract/query_cache.rb +32 -27
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -51
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +10 -20
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +74 -79
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +120 -100
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +49 -43
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +165 -135
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +404 -424
  70. data/lib/active_record/connection_adapters/column.rb +26 -4
  71. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  72. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -28
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +7 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +23 -27
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +32 -53
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +19 -9
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  90. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  91. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +0 -10
  92. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  96. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +32 -30
  97. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  99. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -35
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +182 -222
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +6 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +7 -5
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +198 -167
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -19
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +32 -0
  116. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +184 -167
  117. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  118. data/lib/active_record/connection_handling.rb +14 -26
  119. data/lib/active_record/core.rb +109 -93
  120. data/lib/active_record/counter_cache.rb +60 -13
  121. data/lib/active_record/define_callbacks.rb +20 -0
  122. data/lib/active_record/dynamic_matchers.rb +80 -79
  123. data/lib/active_record/enum.rb +8 -6
  124. data/lib/active_record/errors.rb +64 -15
  125. data/lib/active_record/explain.rb +1 -2
  126. data/lib/active_record/explain_registry.rb +1 -1
  127. data/lib/active_record/explain_subscriber.rb +7 -4
  128. data/lib/active_record/fixture_set/file.rb +11 -8
  129. data/lib/active_record/fixtures.rb +66 -53
  130. data/lib/active_record/gem_version.rb +1 -1
  131. data/lib/active_record/inheritance.rb +93 -79
  132. data/lib/active_record/integration.rb +7 -7
  133. data/lib/active_record/internal_metadata.rb +3 -16
  134. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  135. data/lib/active_record/locking/optimistic.rb +69 -74
  136. data/lib/active_record/locking/pessimistic.rb +10 -1
  137. data/lib/active_record/log_subscriber.rb +23 -28
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +100 -47
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/migration.rb +153 -155
  142. data/lib/active_record/model_schema.rb +94 -107
  143. data/lib/active_record/nested_attributes.rb +200 -199
  144. data/lib/active_record/null_relation.rb +11 -34
  145. data/lib/active_record/persistence.rb +65 -50
  146. data/lib/active_record/query_cache.rb +2 -6
  147. data/lib/active_record/querying.rb +3 -4
  148. data/lib/active_record/railtie.rb +16 -17
  149. data/lib/active_record/railties/controller_runtime.rb +6 -2
  150. data/lib/active_record/railties/databases.rake +105 -133
  151. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  152. data/lib/active_record/readonly_attributes.rb +2 -2
  153. data/lib/active_record/reflection.rb +154 -108
  154. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  155. data/lib/active_record/relation/batches.rb +80 -51
  156. data/lib/active_record/relation/calculations.rb +169 -162
  157. data/lib/active_record/relation/delegation.rb +32 -31
  158. data/lib/active_record/relation/finder_methods.rb +197 -231
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  161. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  162. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  163. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  164. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  165. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  166. data/lib/active_record/relation/predicate_builder.rb +92 -89
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +255 -293
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +80 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/relation.rb +93 -119
  174. data/lib/active_record/result.rb +41 -32
  175. data/lib/active_record/runtime_registry.rb +3 -3
  176. data/lib/active_record/sanitization.rb +176 -192
  177. data/lib/active_record/schema.rb +3 -3
  178. data/lib/active_record/schema_dumper.rb +15 -38
  179. data/lib/active_record/schema_migration.rb +8 -4
  180. data/lib/active_record/scoping/default.rb +90 -90
  181. data/lib/active_record/scoping/named.rb +11 -11
  182. data/lib/active_record/scoping.rb +6 -6
  183. data/lib/active_record/secure_token.rb +2 -2
  184. data/lib/active_record/statement_cache.rb +13 -15
  185. data/lib/active_record/store.rb +31 -32
  186. data/lib/active_record/suppressor.rb +2 -1
  187. data/lib/active_record/table_metadata.rb +9 -5
  188. data/lib/active_record/tasks/database_tasks.rb +65 -55
  189. data/lib/active_record/tasks/mysql_database_tasks.rb +76 -73
  190. data/lib/active_record/tasks/postgresql_database_tasks.rb +72 -47
  191. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  192. data/lib/active_record/timestamp.rb +46 -25
  193. data/lib/active_record/touch_later.rb +1 -2
  194. data/lib/active_record/transactions.rb +97 -109
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +13 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/internal/abstract_json.rb +4 -0
  199. data/lib/active_record/type/serialized.rb +14 -8
  200. data/lib/active_record/type/text.rb +9 -0
  201. data/lib/active_record/type/time.rb +0 -1
  202. data/lib/active_record/type/type_map.rb +11 -15
  203. data/lib/active_record/type/unsigned_integer.rb +15 -0
  204. data/lib/active_record/type.rb +17 -13
  205. data/lib/active_record/type_caster/connection.rb +8 -6
  206. data/lib/active_record/type_caster/map.rb +3 -1
  207. data/lib/active_record/type_caster.rb +2 -2
  208. data/lib/active_record/validations/associated.rb +1 -1
  209. data/lib/active_record/validations/presence.rb +2 -2
  210. data/lib/active_record/validations/uniqueness.rb +8 -39
  211. data/lib/active_record/validations.rb +4 -4
  212. data/lib/active_record/version.rb +1 -1
  213. data/lib/active_record.rb +20 -20
  214. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  215. data/lib/rails/generators/active_record/migration.rb +1 -1
  216. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  217. data/lib/rails/generators/active_record.rb +4 -4
  218. metadata +24 -13
  219. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -111,7 +111,7 @@ module ActiveRecord
111
111
  #
112
112
  # By default, save always runs validations. If any of them fail the action
113
113
  # is cancelled and #save returns +false+, and the record won't be saved. However, if you supply
114
- # validate: false, validations are bypassed altogether. See
114
+ # <tt>validate: false</tt>, validations are bypassed altogether. See
115
115
  # ActiveRecord::Validations for more information.
116
116
  #
117
117
  # By default, #save also sets the +updated_at+/+updated_on+ attributes to
@@ -142,7 +142,7 @@ module ActiveRecord
142
142
  #
143
143
  # By default, #save! always runs validations. If any of them fail
144
144
  # ActiveRecord::RecordInvalid gets raised, and the record won't be saved. However, if you supply
145
- # validate: false, validations are bypassed altogether. See
145
+ # <tt>validate: false</tt>, validations are bypassed altogether. See
146
146
  # ActiveRecord::Validations for more information.
147
147
  #
148
148
  # By default, #save! also sets the +updated_at+/+updated_on+ attributes to
@@ -156,6 +156,8 @@ module ActiveRecord
156
156
  #
157
157
  # Attributes marked as readonly are silently ignored if the record is
158
158
  # being updated.
159
+ #
160
+ # Unless an error is raised, returns true.
159
161
  def save!(*args, &block)
160
162
  create_or_update(*args, &block) || raise(RecordNotSaved.new("Failed to save the record", self))
161
163
  end
@@ -186,10 +188,14 @@ module ActiveRecord
186
188
  # and #destroy returns +false+.
187
189
  # See ActiveRecord::Callbacks for further details.
188
190
  def destroy
189
- raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
191
+ _raise_readonly_record_error if readonly?
190
192
  destroy_associations
191
193
  self.class.connection.add_transaction_record(self)
192
- destroy_row if persisted?
194
+ @_trigger_destroy_callback = if persisted?
195
+ destroy_row > 0
196
+ else
197
+ true
198
+ end
193
199
  @destroyed = true
194
200
  freeze
195
201
  end
@@ -220,7 +226,8 @@ module ActiveRecord
220
226
  def becomes(klass)
221
227
  became = klass.new
222
228
  became.instance_variable_set("@attributes", @attributes)
223
- became.instance_variable_set("@mutation_tracker", @mutation_tracker) if defined?(@mutation_tracker)
229
+ became.instance_variable_set("@mutation_tracker", @mutation_tracker ||= nil)
230
+ became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
224
231
  became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
225
232
  became.instance_variable_set("@new_record", new_record?)
226
233
  became.instance_variable_set("@destroyed", destroyed?)
@@ -261,7 +268,7 @@ module ActiveRecord
261
268
  verify_readonly_attribute(name)
262
269
  public_send("#{name}=", value)
263
270
 
264
- changed? ? save(validate: false) : true
271
+ save(validate: false)
265
272
  end
266
273
 
267
274
  # Updates the attributes of the model from the passed-in hash and saves the
@@ -341,11 +348,13 @@ module ActiveRecord
341
348
  # Wrapper around #increment that writes the update to the database.
342
349
  # Only +attribute+ is updated; the record itself is not saved.
343
350
  # This means that any other modified attributes will still be dirty.
344
- # Validations and callbacks are skipped. Returns +self+.
345
- def increment!(attribute, by = 1)
351
+ # Validations and callbacks are skipped. Supports the `touch` option from
352
+ # +update_counters+, see that for more.
353
+ # Returns +self+.
354
+ def increment!(attribute, by = 1, touch: nil)
346
355
  increment(attribute, by)
347
- change = public_send(attribute) - (attribute_was(attribute.to_s) || 0)
348
- self.class.update_counters(id, attribute => change)
356
+ change = public_send(attribute) - (attribute_in_database(attribute.to_s) || 0)
357
+ self.class.update_counters(id, attribute => change, touch: touch)
349
358
  clear_attribute_change(attribute) # eww
350
359
  self
351
360
  end
@@ -360,9 +369,11 @@ module ActiveRecord
360
369
  # Wrapper around #decrement that writes the update to the database.
361
370
  # Only +attribute+ is updated; the record itself is not saved.
362
371
  # This means that any other modified attributes will still be dirty.
363
- # Validations and callbacks are skipped. Returns +self+.
364
- def decrement!(attribute, by = 1)
365
- increment!(attribute, -by)
372
+ # Validations and callbacks are skipped. Supports the `touch` option from
373
+ # +update_counters+, see that for more.
374
+ # Returns +self+.
375
+ def decrement!(attribute, by = 1, touch: nil)
376
+ increment!(attribute, -by, touch: touch)
366
377
  end
367
378
 
368
379
  # Assigns to +attribute+ the boolean opposite of <tt>attribute?</tt>. So
@@ -392,8 +403,8 @@ module ActiveRecord
392
403
 
393
404
  # Reloads the record from the database.
394
405
  #
395
- # This method finds record by its primary key (which could be assigned manually) and
396
- # modifies the receiver in-place:
406
+ # This method finds the record by its primary key (which could be assigned
407
+ # manually) and modifies the receiver in-place:
397
408
  #
398
409
  # account = Account.new
399
410
  # # => #<Account id: nil, email: nil>
@@ -448,7 +459,7 @@ module ActiveRecord
448
459
  self.class.unscoped { self.class.find(id) }
449
460
  end
450
461
 
451
- @attributes = fresh_object.instance_variable_get('@attributes')
462
+ @attributes = fresh_object.instance_variable_get("@attributes")
452
463
  @new_record = false
453
464
  self
454
465
  end
@@ -495,35 +506,12 @@ module ActiveRecord
495
506
  MSG
496
507
  end
497
508
 
498
- time ||= current_time_from_proper_timezone
499
- attributes = timestamp_attributes_for_update_in_model
500
- attributes.concat(names)
501
-
502
- unless attributes.empty?
503
- changes = {}
504
-
505
- attributes.each do |column|
506
- column = column.to_s
507
- changes[column] = write_attribute(column, time)
508
- end
509
-
510
- clear_attribute_changes(changes.keys)
511
- primary_key = self.class.primary_key
512
- scope = self.class.unscoped.where(primary_key => _read_attribute(primary_key))
513
-
514
- if locking_enabled?
515
- locking_column = self.class.locking_column
516
- scope = scope.where(locking_column => _read_attribute(locking_column))
517
- changes[locking_column] = increment_lock
518
- end
519
-
520
- result = scope.update_all(changes) == 1
509
+ attribute_names = timestamp_attributes_for_update_in_model
510
+ attribute_names |= names.map(&:to_s)
521
511
 
522
- if !result && locking_enabled?
523
- raise ActiveRecord::StaleObjectError.new(self, "touch")
524
- end
525
-
526
- result
512
+ unless attribute_names.empty?
513
+ affected_rows = _touch_row(attribute_names, time)
514
+ @_trigger_update_callback = affected_rows == 1
527
515
  else
528
516
  true
529
517
  end
@@ -543,8 +531,26 @@ module ActiveRecord
543
531
  self.class.unscoped.where(self.class.primary_key => id)
544
532
  end
545
533
 
534
+ def _touch_row(attribute_names, time)
535
+ time ||= current_time_from_proper_timezone
536
+
537
+ attribute_names.each do |attr_name|
538
+ write_attribute(attr_name, time)
539
+ clear_attribute_change(attr_name)
540
+ end
541
+
542
+ _update_row(attribute_names, "touch")
543
+ end
544
+
545
+ def _update_row(attribute_names, attempted_action = "update")
546
+ self.class.unscoped._update_record(
547
+ arel_attributes_with_values(attribute_names),
548
+ self.class.primary_key => id_in_database
549
+ )
550
+ end
551
+
546
552
  def create_or_update(*args, &block)
547
- raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
553
+ _raise_readonly_record_error if readonly?
548
554
  result = new_record? ? _create_record(&block) : _update_record(*args, &block)
549
555
  result != false
550
556
  end
@@ -552,21 +558,26 @@ module ActiveRecord
552
558
  # Updates the associated record with values matching those of the instance attributes.
553
559
  # Returns the number of affected rows.
554
560
  def _update_record(attribute_names = self.attribute_names)
555
- attributes_values = arel_attributes_with_values_for_update(attribute_names)
556
- if attributes_values.empty?
557
- rows_affected = 0
561
+ attribute_names &= self.class.column_names
562
+ attribute_names = attributes_for_update(attribute_names)
563
+
564
+ if attribute_names.empty?
565
+ affected_rows = 0
566
+ @_trigger_update_callback = true
558
567
  else
559
- rows_affected = self.class.unscoped._update_record attributes_values, id, id_was
568
+ affected_rows = _update_row(attribute_names)
569
+ @_trigger_update_callback = affected_rows == 1
560
570
  end
561
571
 
562
572
  yield(self) if block_given?
563
573
 
564
- rows_affected
574
+ affected_rows
565
575
  end
566
576
 
567
577
  # Creates a record with values matching those of the instance attributes
568
578
  # and returns its id.
569
579
  def _create_record(attribute_names = self.attribute_names)
580
+ attribute_names &= self.class.column_names
570
581
  attributes_values = arel_attributes_with_values_for_create(attribute_names)
571
582
 
572
583
  new_id = self.class.unscoped.insert attributes_values
@@ -593,5 +604,9 @@ module ActiveRecord
593
604
  def belongs_to_touch_method
594
605
  :touch
595
606
  end
607
+
608
+ def _raise_readonly_record_error
609
+ raise ReadOnlyRecord, "#{self.class} is marked as readonly"
610
+ end
596
611
  end
597
612
  end
@@ -24,19 +24,15 @@ module ActiveRecord
24
24
  end
25
25
 
26
26
  def self.run
27
- connection_id = ActiveRecord::Base.connection_id
28
-
29
27
  caching_pool = ActiveRecord::Base.connection_pool
30
28
  caching_was_enabled = caching_pool.query_cache_enabled
31
29
 
32
30
  caching_pool.enable_query_cache!
33
31
 
34
- [caching_pool, caching_was_enabled, connection_id]
32
+ [caching_pool, caching_was_enabled]
35
33
  end
36
34
 
37
- def self.complete((caching_pool, caching_was_enabled, connection_id))
38
- ActiveRecord::Base.connection_id = connection_id
39
-
35
+ def self.complete((caching_pool, caching_was_enabled))
40
36
  caching_pool.disable_query_cache! unless caching_was_enabled
41
37
 
42
38
  ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
@@ -8,8 +8,8 @@ module ActiveRecord
8
8
  delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all
9
9
  delegate :find_each, :find_in_batches, :in_batches, to: :all
10
10
  delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
11
- :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly,
12
- :having, :create_with, :uniq, :distinct, :references, :none, :unscope, to: :all
11
+ :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
12
+ :having, :create_with, :distinct, :references, :none, :unscope, :merge, to: :all
13
13
  delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all
14
14
  delegate :pluck, :ids, to: :all
15
15
 
@@ -62,8 +62,7 @@ module ActiveRecord
62
62
  #
63
63
  # * +sql+ - An SQL statement which should return a count query from the database, see the example above.
64
64
  def count_by_sql(sql)
65
- sql = sanitize_conditions(sql)
66
- connection.select_value(sql, "#{name} Count").to_i
65
+ connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
67
66
  end
68
67
  end
69
68
  end
@@ -3,7 +3,7 @@ require "rails"
3
3
  require "active_model/railtie"
4
4
 
5
5
  # For now, action_controller must always be present with
6
- # rails, so let's make sure that it gets required before
6
+ # Rails, so let's make sure that it gets required before
7
7
  # here. This is needed for correctly setting up the middleware.
8
8
  # In the future, this might become an optional require.
9
9
  require "action_controller/railtie"
@@ -13,17 +13,16 @@ module ActiveRecord
13
13
  class Railtie < Rails::Railtie # :nodoc:
14
14
  config.active_record = ActiveSupport::OrderedOptions.new
15
15
 
16
- config.app_generators.orm :active_record, :migration => true,
17
- :timestamps => true
16
+ config.app_generators.orm :active_record, migration: true,
17
+ timestamps: true
18
18
 
19
19
  config.action_dispatch.rescue_responses.merge!(
20
- 'ActiveRecord::RecordNotFound' => :not_found,
21
- 'ActiveRecord::StaleObjectError' => :conflict,
22
- 'ActiveRecord::RecordInvalid' => :unprocessable_entity,
23
- 'ActiveRecord::RecordNotSaved' => :unprocessable_entity
20
+ "ActiveRecord::RecordNotFound" => :not_found,
21
+ "ActiveRecord::StaleObjectError" => :conflict,
22
+ "ActiveRecord::RecordInvalid" => :unprocessable_entity,
23
+ "ActiveRecord::RecordNotSaved" => :unprocessable_entity
24
24
  )
25
25
 
26
-
27
26
  config.active_record.use_schema_cache_dump = true
28
27
  config.active_record.maintain_test_schema = true
29
28
 
@@ -35,8 +34,8 @@ module ActiveRecord
35
34
  ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
36
35
 
37
36
  if defined?(ENGINE_ROOT) && engine = Rails::Engine.find(ENGINE_ROOT)
38
- if engine.paths['db/migrate'].existent
39
- ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths['db/migrate'].to_a
37
+ if engine.paths["db/migrate"].existent
38
+ ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths["db/migrate"].to_a
40
39
  end
41
40
  end
42
41
  end
@@ -83,15 +82,15 @@ module ActiveRecord
83
82
  if config.active_record.delete(:use_schema_cache_dump)
84
83
  config.after_initialize do |app|
85
84
  ActiveSupport.on_load(:active_record) do
86
- filename = File.join(app.config.paths["db"].first, "schema_cache.dump")
85
+ filename = File.join(app.config.paths["db"].first, "schema_cache.yml")
87
86
 
88
87
  if File.file?(filename)
89
- cache = Marshal.load File.binread filename
88
+ cache = YAML.load(File.read(filename))
90
89
  if cache.version == ActiveRecord::Migrator.current_version
91
- self.connection.schema_cache = cache
92
- self.connection_pool.schema_cache = cache.dup
90
+ connection.schema_cache = cache
91
+ connection_pool.schema_cache = cache.dup
93
92
  else
94
- warn "Ignoring db/schema_cache.dump because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}."
93
+ warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}."
95
94
  end
96
95
  end
97
96
  end
@@ -102,14 +101,14 @@ module ActiveRecord
102
101
  initializer "active_record.warn_on_records_fetched_greater_than" do
103
102
  if config.active_record.warn_on_records_fetched_greater_than
104
103
  ActiveSupport.on_load(:active_record) do
105
- require 'active_record/relation/record_fetch_warning'
104
+ require "active_record/relation/record_fetch_warning"
106
105
  end
107
106
  end
108
107
  end
109
108
 
110
109
  initializer "active_record.set_configs" do |app|
111
110
  ActiveSupport.on_load(:active_record) do
112
- app.config.active_record.each do |k,v|
111
+ app.config.active_record.each do |k, v|
113
112
  send "#{k}=", v
114
113
  end
115
114
  end
@@ -1,15 +1,19 @@
1
- require 'active_support/core_ext/module/attr_internal'
2
- require 'active_record/log_subscriber'
1
+ require "active_support/core_ext/module/attr_internal"
2
+ require "active_record/log_subscriber"
3
3
 
4
4
  module ActiveRecord
5
5
  module Railties # :nodoc:
6
6
  module ControllerRuntime #:nodoc:
7
7
  extend ActiveSupport::Concern
8
8
 
9
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
10
+ # Workaround for Ruby 2.2 "private attribute?" warning.
9
11
  protected
10
12
 
11
13
  attr_internal :db_runtime
12
14
 
15
+ private
16
+
13
17
  def process_action(action, *args)
14
18
  # We also need to reset the runtime before each action
15
19
  # because of queries in middleware or in cases we are streaming