activerecord 5.2.1 → 5.2.5

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +228 -0
  3. data/lib/active_record/association_relation.rb +3 -3
  4. data/lib/active_record/associations/association.rb +8 -0
  5. data/lib/active_record/associations/builder/collection_association.rb +2 -2
  6. data/lib/active_record/associations/collection_association.rb +9 -8
  7. data/lib/active_record/associations/collection_proxy.rb +8 -34
  8. data/lib/active_record/associations/has_many_association.rb +9 -0
  9. data/lib/active_record/associations/has_many_through_association.rb +28 -11
  10. data/lib/active_record/associations/join_dependency/join_association.rb +28 -7
  11. data/lib/active_record/associations/preloader.rb +1 -1
  12. data/lib/active_record/attribute_methods/dirty.rb +13 -8
  13. data/lib/active_record/autosave_association.rb +25 -11
  14. data/lib/active_record/callbacks.rb +1 -1
  15. data/lib/active_record/collection_cache_key.rb +2 -2
  16. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +36 -11
  17. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  18. data/lib/active_record/connection_adapters/abstract/database_statements.rb +19 -6
  19. data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -3
  20. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +3 -3
  21. data/lib/active_record/connection_adapters/abstract_adapter.rb +3 -1
  22. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +18 -8
  23. data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
  24. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -2
  25. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +7 -1
  26. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  27. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
  28. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +10 -24
  29. data/lib/active_record/connection_adapters/postgresql/utils.rb +1 -1
  30. data/lib/active_record/connection_adapters/postgresql_adapter.rb +9 -1
  31. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +4 -0
  32. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +3 -3
  33. data/lib/active_record/core.rb +2 -1
  34. data/lib/active_record/enum.rb +1 -0
  35. data/lib/active_record/errors.rb +18 -12
  36. data/lib/active_record/gem_version.rb +1 -1
  37. data/lib/active_record/migration.rb +1 -1
  38. data/lib/active_record/migration/compatibility.rb +15 -15
  39. data/lib/active_record/model_schema.rb +1 -1
  40. data/lib/active_record/persistence.rb +5 -4
  41. data/lib/active_record/querying.rb +1 -1
  42. data/lib/active_record/railtie.rb +1 -3
  43. data/lib/active_record/reflection.rb +10 -14
  44. data/lib/active_record/relation.rb +26 -7
  45. data/lib/active_record/relation/calculations.rb +16 -12
  46. data/lib/active_record/relation/delegation.rb +30 -0
  47. data/lib/active_record/relation/finder_methods.rb +8 -4
  48. data/lib/active_record/relation/merger.rb +8 -5
  49. data/lib/active_record/relation/predicate_builder.rb +14 -9
  50. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  51. data/lib/active_record/relation/query_attribute.rb +5 -3
  52. data/lib/active_record/relation/query_methods.rb +35 -10
  53. data/lib/active_record/relation/spawn_methods.rb +1 -1
  54. data/lib/active_record/scoping/default.rb +2 -2
  55. data/lib/active_record/scoping/named.rb +2 -0
  56. data/lib/active_record/statement_cache.rb +2 -2
  57. data/lib/active_record/tasks/database_tasks.rb +1 -1
  58. data/lib/active_record/transactions.rb +1 -1
  59. metadata +9 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b480ac3395548916f9d2dd47e4b26eebab5e415cf32b51e7632bad78bf22dce9
4
- data.tar.gz: 2f07a2153ae96236fcabe811139a9660273acff5bc042ed586934b4cb7207e45
3
+ metadata.gz: 305cecf2df5a26287bc4f1a68e908bb0be484ab49d45d76a6e0ba1f2e99be96a
4
+ data.tar.gz: ec6f7cff6950599833fd0abca1d2133d632574d50c473596c2526f5bf16dd681
5
5
  SHA512:
6
- metadata.gz: a10d5aafe0fda079ccdeba3830674496e504c20549bb271df72cc099f63cdf10765766c13e30830b2960df7527a6aa3f499856e81e1f6baff74b61221f5c301c
7
- data.tar.gz: 5509181237ce0872ecb1662b4a31cb7ef5c85b66fe9626e6bad9869e76b9649b8bb3c3f4e91bdf31aea86ae86174a6c83da2fcfc4df2622eddbb628fc0ca3d1c
6
+ metadata.gz: ddcc02e64425cee7036e9faf08405e91b753f782b878bfb4ac16909ff2894cc37deff27bbf4500f933d262608dda6565c8a4364f195ecc9a8168bfa66aa7f28d
7
+ data.tar.gz: 9ec8898d502f1381d02e49ce42817a5b7a95d433a895b2fe53de8b3afd6b50af79f4cb1e863fbb634714fe80d663234a754e52dc63ed19caf0fc7b2ae4f6c5b5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,231 @@
1
+ ## Rails 5.2.5 (March 26, 2021) ##
2
+
3
+ * No changes.
4
+
5
+
6
+ ## Rails 5.2.4.5 (February 10, 2021) ##
7
+
8
+ * Fix possible DoS vector in PostgreSQL money type
9
+
10
+ Carefully crafted input can cause a DoS via the regular expressions used
11
+ for validating the money format in the PostgreSQL adapter. This patch
12
+ fixes the regexp.
13
+
14
+ Thanks to @dee-see from Hackerone for this patch!
15
+
16
+ [CVE-2021-22880]
17
+
18
+ *Aaron Patterson*
19
+
20
+
21
+ ## Rails 5.2.4.4 (September 09, 2020) ##
22
+
23
+ * No changes.
24
+
25
+
26
+ ## Rails 5.2.4.3 (May 18, 2020) ##
27
+
28
+ * No changes.
29
+
30
+ ## Rails 5.2.4.2 (March 19, 2020) ##
31
+
32
+ * No changes.
33
+
34
+
35
+ ## Rails 5.2.4.1 (December 18, 2019) ##
36
+
37
+ * No changes.
38
+
39
+
40
+ ## Rails 5.2.4 (November 27, 2019) ##
41
+
42
+ * Fix circular `autosave: true` causes invalid records to be saved.
43
+
44
+ Prior to the fix, when there was a circular series of `autosave: true`
45
+ associations, the callback for a `has_many` association was run while
46
+ another instance of the same callback on the same association hadn't
47
+ finished running. When control returned to the first instance of the
48
+ callback, the instance variable had changed, and subsequent associated
49
+ records weren't saved correctly. Specifically, the ID field for the
50
+ `belongs_to` corresponding to the `has_many` was `nil`.
51
+
52
+ Fixes #28080.
53
+
54
+ *Larry Reid*
55
+
56
+ * PostgreSQL: Fix GROUP BY with ORDER BY virtual count attribute.
57
+
58
+ Fixes #36022.
59
+
60
+ *Ryuta Kamizono*
61
+
62
+ * Fix sqlite3 collation parsing when using decimal columns.
63
+
64
+ *Martin R. Schuster*
65
+
66
+ * Make ActiveRecord `ConnectionPool.connections` method thread-safe.
67
+
68
+ Fixes #36465.
69
+
70
+ *Jeff Doering*
71
+
72
+ * Assign all attributes before calling `build` to ensure the child record is visible in
73
+ `before_add` and `after_add` callbacks for `has_many :through` associations.
74
+
75
+ Fixes #33249.
76
+
77
+ *Ryan H. Kerr*
78
+
79
+
80
+ ## Rails 5.2.3 (March 27, 2019) ##
81
+
82
+ * Fix different `count` calculation when using `size` with manual `select` with DISTINCT.
83
+
84
+ Fixes #35214.
85
+
86
+ *Juani Villarejo*
87
+
88
+ * Fix prepared statements caching to be enabled even when query caching is enabled.
89
+
90
+ *Ryuta Kamizono*
91
+
92
+ * Don't allow `where` with invalid value matches to nil values.
93
+
94
+ Fixes #33624.
95
+
96
+ *Ryuta Kamizono*
97
+
98
+ * Restore an ability that class level `update` without giving ids.
99
+
100
+ Fixes #34743.
101
+
102
+ *Ryuta Kamizono*
103
+
104
+ * Fix join table column quoting with SQLite.
105
+
106
+ *Gannon McGibbon*
107
+
108
+ * Ensure that `delete_all` on collection proxy returns affected count.
109
+
110
+ *Ryuta Kamizono*
111
+
112
+ * Reset scope after delete on collection association to clear stale offsets of removed records.
113
+
114
+ *Gannon McGibbon*
115
+
116
+
117
+ ## Rails 5.2.2.1 (March 11, 2019) ##
118
+
119
+ * No changes.
120
+
121
+
122
+ ## Rails 5.2.2 (December 04, 2018) ##
123
+
124
+ * Do not ignore the scoping with query methods in the scope block.
125
+
126
+ *Ryuta Kamizono*
127
+
128
+ * Allow aliased attributes to be used in `#update_columns` and `#update`.
129
+
130
+ *Gannon McGibbon*
131
+
132
+ * Allow spaces in postgres table names.
133
+
134
+ Fixes issue where "user post" is misinterpreted as "\"user\".\"post\"" when quoting table names with the postgres
135
+ adapter.
136
+
137
+ *Gannon McGibbon*
138
+
139
+ * Cached columns_hash fields should be excluded from ResultSet#column_types
140
+
141
+ PR #34528 addresses the inconsistent behaviour when attribute is defined for an ignored column. The following test
142
+ was passing for SQLite and MySQL, but failed for PostgreSQL:
143
+
144
+ ```ruby
145
+ class DeveloperName < ActiveRecord::Type::String
146
+ def deserialize(value)
147
+ "Developer: #{value}"
148
+ end
149
+ end
150
+
151
+ class AttributedDeveloper < ActiveRecord::Base
152
+ self.table_name = "developers"
153
+
154
+ attribute :name, DeveloperName.new
155
+
156
+ self.ignored_columns += ["name"]
157
+ end
158
+
159
+ developer = AttributedDeveloper.create
160
+ developer.update_column :name, "name"
161
+
162
+ loaded_developer = AttributedDeveloper.where(id: developer.id).select("*").first
163
+ puts loaded_developer.name # should be "Developer: name" but it's just "name"
164
+ ```
165
+
166
+ *Dmitry Tsepelev*
167
+
168
+ * Values of enum are frozen, raising an error when attempting to modify them.
169
+
170
+ *Emmanuel Byrd*
171
+
172
+ * `update_columns` now correctly raises `ActiveModel::MissingAttributeError`
173
+ if the attribute does not exist.
174
+
175
+ *Sean Griffin*
176
+
177
+ * Do not use prepared statement in queries that have a large number of binds.
178
+
179
+ *Ryuta Kamizono*
180
+
181
+ * Fix query cache to load before first request.
182
+
183
+ *Eileen M. Uchitelle*
184
+
185
+ * Fix collection cache key with limit and custom select to avoid ambiguous timestamp column error.
186
+
187
+ Fixes #33056.
188
+
189
+ *Federico Martinez*
190
+
191
+ * Fix duplicated record creation when using nested attributes with `create_with`.
192
+
193
+ *Darwin Wu*
194
+
195
+ * Fix regression setting children record in parent `before_save` callback.
196
+
197
+ *Guo Xiang Tan*
198
+
199
+ * Prevent leaking of user's DB credentials on `rails db:create` failure.
200
+
201
+ *bogdanvlviv*
202
+
203
+ * Clear mutation tracker before continuing the around callbacks.
204
+
205
+ *Yuya Tanaka*
206
+
207
+ * Prevent deadlocks when waiting for connection from pool.
208
+
209
+ *Brent Wheeldon*
210
+
211
+ * Avoid extra scoping when using `Relation#update` that was causing this method to change the current scope.
212
+
213
+ *Ryuta Kamizono*
214
+
215
+ * Fix numericality validator not to be affected by custom getter.
216
+
217
+ *Ryuta Kamizono*
218
+
219
+ * Fix bulk change table ignores comment option on PostgreSQL.
220
+
221
+ *Yoshiyuki Kinjo*
222
+
223
+
224
+ ## Rails 5.2.1.1 (November 27, 2018) ##
225
+
226
+ * No changes.
227
+
228
+
1
229
  ## Rails 5.2.1 (August 07, 2018) ##
2
230
 
3
231
  * PostgreSQL: Support new relkind for partitioned tables.
@@ -31,9 +31,9 @@ module ActiveRecord
31
31
  private
32
32
 
33
33
  def exec_queries
34
- super do |r|
35
- @association.set_inverse_instance r
36
- yield r if block_given?
34
+ super do |record|
35
+ @association.set_inverse_instance_from_queries(record)
36
+ yield record if block_given?
37
37
  end
38
38
  end
39
39
  end
@@ -103,6 +103,13 @@ module ActiveRecord
103
103
  record
104
104
  end
105
105
 
106
+ def set_inverse_instance_from_queries(record)
107
+ if inverse = inverse_association_for(record)
108
+ inverse.inversed_from_queries(owner)
109
+ end
110
+ record
111
+ end
112
+
106
113
  # Remove the inverse association, if possible
107
114
  def remove_inverse_instance(record)
108
115
  if inverse = inverse_association_for(record)
@@ -114,6 +121,7 @@ module ActiveRecord
114
121
  self.target = record
115
122
  @inversed = !!record
116
123
  end
124
+ alias :inversed_from_queries :inversed_from
117
125
 
118
126
  # Returns the class of the target. belongs_to polymorphic overrides this to look at the
119
127
  # polymorphic_type field on the owner.
@@ -20,10 +20,10 @@ module ActiveRecord::Associations::Builder # :nodoc:
20
20
  }
21
21
  end
22
22
 
23
- def self.define_extensions(model, name)
23
+ def self.define_extensions(model, name, &block)
24
24
  if block_given?
25
25
  extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
26
- extension = Module.new(&Proc.new)
26
+ extension = Module.new(&block)
27
27
  model.parent.const_set(extension_module_name, extension)
28
28
  end
29
29
  end
@@ -45,6 +45,8 @@ module ActiveRecord
45
45
  def ids_reader
46
46
  if loaded?
47
47
  target.pluck(reflection.association_primary_key)
48
+ elsif !target.empty?
49
+ load_target.pluck(reflection.association_primary_key)
48
50
  else
49
51
  @association_ids ||= scope.pluck(reflection.association_primary_key)
50
52
  end
@@ -107,9 +109,8 @@ module ActiveRecord
107
109
  end
108
110
  end
109
111
 
110
- # Add +records+ to this association. Returns +self+ so method calls may
111
- # be chained. Since << flattens its argument list and inserts each record,
112
- # +push+ and +concat+ behave identically.
112
+ # Add +records+ to this association. Since +<<+ flattens its argument list
113
+ # and inserts each record, +push+ and +concat+ behave identically.
113
114
  def concat(*records)
114
115
  records = records.flatten
115
116
  if owner.new_record?
@@ -360,7 +361,6 @@ module ActiveRecord
360
361
  add_to_target(record) do
361
362
  result = insert_record(record, true, raise) {
362
363
  @_was_loaded = loaded?
363
- @association_ids = nil
364
364
  }
365
365
  end
366
366
  raise ActiveRecord::Rollback unless result
@@ -397,6 +397,7 @@ module ActiveRecord
397
397
 
398
398
  delete_records(existing_records, method) if existing_records.any?
399
399
  records.each { |record| target.delete(record) }
400
+ @association_ids = nil
400
401
 
401
402
  records.each { |record| callback(:after_remove, record) }
402
403
  end
@@ -409,9 +410,9 @@ module ActiveRecord
409
410
  end
410
411
 
411
412
  def replace_records(new_target, original_target)
412
- delete(target - new_target)
413
+ delete(difference(target, new_target))
413
414
 
414
- unless concat(new_target - target)
415
+ unless concat(difference(new_target, target))
415
416
  @target = original_target
416
417
  raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
417
418
  "new records could not be saved."
@@ -421,7 +422,7 @@ module ActiveRecord
421
422
  end
422
423
 
423
424
  def replace_common_records_in_memory(new_target, original_target)
424
- common_records = new_target & original_target
425
+ common_records = intersection(new_target, original_target)
425
426
  common_records.each do |record|
426
427
  skip_callbacks = true
427
428
  replace_on_target(record, @target.index(record), skip_callbacks)
@@ -437,7 +438,6 @@ module ActiveRecord
437
438
  unless owner.new_record?
438
439
  result &&= insert_record(record, true, raise) {
439
440
  @_was_loaded = loaded?
440
- @association_ids = nil
441
441
  }
442
442
  end
443
443
  end
@@ -460,6 +460,7 @@ module ActiveRecord
460
460
  if index
461
461
  target[index] = record
462
462
  elsif @_was_loaded || !loaded?
463
+ @association_ids = nil
463
464
  target << record
464
465
  end
465
466
 
@@ -366,34 +366,6 @@ module ActiveRecord
366
366
  @association.create!(attributes, &block)
367
367
  end
368
368
 
369
- # Add one or more records to the collection by setting their foreign keys
370
- # to the association's primary key. Since #<< flattens its argument list and
371
- # inserts each record, +push+ and #concat behave identically. Returns +self+
372
- # so method calls may be chained.
373
- #
374
- # class Person < ActiveRecord::Base
375
- # has_many :pets
376
- # end
377
- #
378
- # person.pets.size # => 0
379
- # person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
380
- # person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
381
- # person.pets.size # => 3
382
- #
383
- # person.id # => 1
384
- # person.pets
385
- # # => [
386
- # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
387
- # # #<Pet id: 2, name: "Spook", person_id: 1>,
388
- # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
389
- # # ]
390
- #
391
- # person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
392
- # person.pets.size # => 5
393
- def concat(*records)
394
- @association.concat(*records)
395
- end
396
-
397
369
  # Replaces this collection with +other_array+. This will perform a diff
398
370
  # and delete/add only records that have changed.
399
371
  #
@@ -500,7 +472,7 @@ module ActiveRecord
500
472
  # Pet.find(1, 2, 3)
501
473
  # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
502
474
  def delete_all(dependent = nil)
503
- @association.delete_all(dependent)
475
+ @association.delete_all(dependent).tap { reset_scope }
504
476
  end
505
477
 
506
478
  # Deletes the records of the collection directly from the database
@@ -527,7 +499,7 @@ module ActiveRecord
527
499
  #
528
500
  # Pet.find(1) # => Couldn't find Pet with id=1
529
501
  def destroy_all
530
- @association.destroy_all
502
+ @association.destroy_all.tap { reset_scope }
531
503
  end
532
504
 
533
505
  # Deletes the +records+ supplied from the collection according to the strategy
@@ -646,7 +618,7 @@ module ActiveRecord
646
618
  # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
647
619
  # # ]
648
620
  def delete(*records)
649
- @association.delete(*records)
621
+ @association.delete(*records).tap { reset_scope }
650
622
  end
651
623
 
652
624
  # Destroys the +records+ supplied and removes them from the collection.
@@ -718,7 +690,7 @@ module ActiveRecord
718
690
  #
719
691
  # Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
720
692
  def destroy(*records)
721
- @association.destroy(*records)
693
+ @association.destroy(*records).tap { reset_scope }
722
694
  end
723
695
 
724
696
  ##
@@ -1033,8 +1005,9 @@ module ActiveRecord
1033
1005
  end
1034
1006
 
1035
1007
  # Adds one or more +records+ to the collection by setting their foreign keys
1036
- # to the association's primary key. Returns +self+, so several appends may be
1037
- # chained together.
1008
+ # to the association's primary key. Since +<<+ flattens its argument list and
1009
+ # inserts each record, +push+ and +concat+ behave identically. Returns +self+
1010
+ # so several appends may be chained together.
1038
1011
  #
1039
1012
  # class Person < ActiveRecord::Base
1040
1013
  # has_many :pets
@@ -1057,6 +1030,7 @@ module ActiveRecord
1057
1030
  end
1058
1031
  alias_method :push, :<<
1059
1032
  alias_method :append, :<<
1033
+ alias_method :concat, :<<
1060
1034
 
1061
1035
  def prepend(*args)
1062
1036
  raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"