activerecord 5.2.0.rc1 → 5.2.0.rc2

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +75 -16
  3. data/README.rdoc +1 -1
  4. data/lib/active_record/associations/association.rb +4 -4
  5. data/lib/active_record/associations/association_scope.rb +6 -6
  6. data/lib/active_record/associations/belongs_to_association.rb +9 -1
  7. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  8. data/lib/active_record/associations/has_one_association.rb +1 -0
  9. data/lib/active_record/associations/join_dependency.rb +2 -4
  10. data/lib/active_record/associations/preloader/association.rb +1 -1
  11. data/lib/active_record/attribute_assignment.rb +0 -5
  12. data/lib/active_record/attribute_methods.rb +19 -14
  13. data/lib/active_record/attribute_methods/dirty.rb +4 -2
  14. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  15. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1 -1
  16. data/lib/active_record/connection_adapters/abstract_adapter.rb +2 -2
  17. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1 -1
  18. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -0
  19. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  20. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +2 -2
  21. data/lib/active_record/connection_adapters/postgresql_adapter.rb +2 -1
  22. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  23. data/lib/active_record/gem_version.rb +1 -1
  24. data/lib/active_record/inheritance.rb +40 -10
  25. data/lib/active_record/locking/optimistic.rb +27 -41
  26. data/lib/active_record/migration.rb +8 -2
  27. data/lib/active_record/model_schema.rb +1 -0
  28. data/lib/active_record/persistence.rb +60 -51
  29. data/lib/active_record/query_cache.rb +6 -6
  30. data/lib/active_record/railties/databases.rake +1 -1
  31. data/lib/active_record/reflection.rb +7 -4
  32. data/lib/active_record/relation/calculations.rb +1 -1
  33. data/lib/active_record/relation/finder_methods.rb +3 -3
  34. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +7 -5
  35. data/lib/active_record/relation/predicate_builder/range_handler.rb +4 -3
  36. data/lib/active_record/relation/query_attribute.rb +17 -0
  37. data/lib/active_record/validations/uniqueness.rb +1 -1
  38. metadata +10 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93d18124cf004be27375ca0f77a70d56b880796ee10d10dada17e2fe8db884e4
4
- data.tar.gz: d8a7fbd5fd738a36fb7bbbbddebeb4f1e3ceec661f81fa31a545decd3c30b19c
3
+ metadata.gz: eb425b995eed9a7eaf3b93644266bdd4a88f49f95b26edaf134ecf57b5e021fd
4
+ data.tar.gz: 8aa207b5a556cfe2d3436db7b727a19dde4b23bbfa1ab5dde6488b29599f5bcb
5
5
  SHA512:
6
- metadata.gz: 4b80509910c2c049cbdb41b24babb91bd0562709e4939894b9686d0516fd38e2ab30f0e009cb38205d57e19ab83952b53e1ab1f8e7b8741a4c552e416c1025b9
7
- data.tar.gz: 6d848c3decb422926c55d2d9102c2d1e7d5d36c27d0d3b39b0fb6973533283e1e051a687f0da141c2ab8d3b1958b01d1e98c362b56f8455883a6366f7a08bd97
6
+ metadata.gz: aa5cfa06bf456169fd76770101a51d1674c5178aba4cbed99000f1c9e4ee5dd7b2da131d3f3d252f21d904c31d8669fcf38977f7c9808d02b403c54510ef721b
7
+ data.tar.gz: 653ad19017c710263edbe37f20fcf6fbf819e6585ea6ef3ce1a70041e6464201b4dea9166d5cff703384f063dabb33033125dbb7e9101886312bf7f06beec32e
@@ -1,5 +1,68 @@
1
+ ## Rails 5.2.0.rc2 (March 20, 2018) ##
2
+
3
+ * Apply time column precision on assignment.
4
+
5
+ PR #20317 changed the behavior of datetime columns so that when they
6
+ have a specified precision then on assignment the value is rounded to
7
+ that precision. This behavior is now applied to time columns as well.
8
+
9
+ Fixes #30301.
10
+
11
+ *Andrew White*
12
+
13
+ * Normalize time column values for SQLite database.
14
+
15
+ For legacy reasons, time columns in SQLite are stored as full datetimes
16
+ because until #24542 the quoting for time columns didn't remove the date
17
+ component. To ensure that values are consistent we now normalize the
18
+ date component to 2001-01-01 on reading and writing.
19
+
20
+ *Andrew White*
21
+
22
+ * Ensure that the date component is removed when quoting times.
23
+
24
+ PR #24542 altered the quoting for time columns so that the date component
25
+ was removed however it only removed it when it was 2001-01-01. Now the
26
+ date component is removed irrespective of what the date is.
27
+
28
+ *Andrew White*
29
+
30
+ * Fix `dependent: :destroy` issue for has_one/belongs_to relationship where
31
+ the parent class was getting deleted when the child was not.
32
+
33
+ Fixes #32022.
34
+
35
+ *Fernando Gorodscy*
36
+
37
+ * Whitelist `NULLS FIRST` and `NULLS LAST` in order clauses too.
38
+
39
+ *Xavier Noria*
40
+
41
+ * Fix that after commit callbacks on update does not triggered when optimistic locking is enabled.
42
+
43
+ *Ryuta Kamizono*
44
+
45
+ * Fix `#columns_for_distinct` of MySQL and PostgreSQL to make
46
+ `ActiveRecord::FinderMethods#limited_ids_for` use correct primary key values
47
+ even if `ORDER BY` columns include other table's primary key.
48
+
49
+ Fixes #28364.
50
+
51
+ *Takumi Kagiyama*
52
+
53
+ * Make `reflection.klass` raise if `polymorphic?` not to be misused.
54
+
55
+ Fixes #31876.
56
+
57
+ *Ryuta Kamizono*
58
+
59
+
1
60
  ## Rails 5.2.0.rc1 (January 30, 2018) ##
2
61
 
62
+ * PostgreSQL: Allow pg-1.0 gem to be used with Active Record.
63
+
64
+ *Lars Kanis*
65
+
3
66
  * Deprecate `expand_hash_conditions_for_aggregates` without replacement.
4
67
  Using a `Relation` for performing queries is the prefered API.
5
68
 
@@ -117,7 +180,7 @@
117
180
 
118
181
  *Chris Salzberg*
119
182
 
120
- * Log database query callers
183
+ * Log database query callers.
121
184
 
122
185
  Add `verbose_query_logs` configuration option to display the caller
123
186
  of database queries in the log to facilitate N+1 query resolution
@@ -352,7 +415,7 @@
352
415
 
353
416
  *Rafael Mendonça França*
354
417
 
355
- * Fix `bin/rails db:setup` and `bin/rails db:test:prepare` create wrong
418
+ * Fix `bin/rails db:setup` and `bin/rails db:test:prepare` create wrong
356
419
  ar_internal_metadata's data for a test database.
357
420
 
358
421
  Before:
@@ -444,7 +507,7 @@
444
507
 
445
508
  *Yuichiro Kaneko*
446
509
 
447
- * Ensure `sum` honors `distinct` on `has_many :through` associations
510
+ * Ensure `sum` honors `distinct` on `has_many :through` associations.
448
511
 
449
512
  Fixes #16791.
450
513
 
@@ -480,7 +543,7 @@
480
543
 
481
544
  *Lisa Ugray*
482
545
 
483
- * Fix `unscoped(where: [columns])` removing the wrong bind values
546
+ * Fix `unscoped(where: [columns])` removing the wrong bind values.
484
547
 
485
548
  When the `where` is called on a relation after a `or`, unscoping the column of that later `where` removed
486
549
  bind values used by the `or` instead. (possibly other cases too)
@@ -507,7 +570,7 @@
507
570
 
508
571
  *Sean Griffin*
509
572
 
510
- * Change sqlite3 boolean serialization to use 1 and 0
573
+ * Change sqlite3 boolean serialization to use 1 and 0.
511
574
 
512
575
  SQLite natively recognizes 1 and 0 as true and false, but does not natively
513
576
  recognize 't' and 'f' as was previously serialized.
@@ -537,7 +600,7 @@
537
600
 
538
601
  *Ryuta Kamizono*
539
602
 
540
- * Fix transactions to apply state to child transactions
603
+ * Fix transactions to apply state to child transactions.
541
604
 
542
605
  Previously, if you had a nested transaction and the outer transaction was rolledback, the record from the
543
606
  inner transaction would still be marked as persisted.
@@ -547,7 +610,7 @@
547
610
 
548
611
  *Eileen M. Uchitelle*, *Aaron Patterson*
549
612
 
550
- * Deprecate `set_state` method in `TransactionState`
613
+ * Deprecate `set_state` method in `TransactionState`.
551
614
 
552
615
  Deprecated the `set_state` method in favor of setting the state via specific methods. If you need to mark the
553
616
  state of the transaction you can now use `rollback!`, `commit!` or `nullify!` instead of
@@ -559,10 +622,6 @@
559
622
 
560
623
  *Ryuta Kamizono*
561
624
 
562
- * Fix eager loading to respect `store_full_sti_class` setting.
563
-
564
- *Ryuta Kamizono*
565
-
566
625
  * Query cache was unavailable when entering the `ActiveRecord::Base.cache` block
567
626
  without being connected.
568
627
 
@@ -576,7 +635,9 @@
576
635
  *Tobias Kraze*
577
636
 
578
637
  * Merging two relations representing nested joins no longer transforms the joins of
579
- the merged relation into LEFT OUTER JOIN. Example to clarify:
638
+ the merged relation into LEFT OUTER JOIN.
639
+
640
+ Example:
580
641
 
581
642
  ```
582
643
  Author.joins(:posts).merge(Post.joins(:comments))
@@ -587,8 +648,6 @@
587
648
  #=> SELECT ... FROM authors INNER JOIN posts ON ... INNER JOIN comments ON...
588
649
  ```
589
650
 
590
- TODO: Add to the Rails 5.2 upgrade guide
591
-
592
651
  *Maxime Handfield Lapointe*
593
652
 
594
653
  * `ActiveRecord::Persistence#touch` does not work well when optimistic locking enabled and
@@ -628,11 +687,11 @@
628
687
 
629
688
  *DHH*
630
689
 
631
- * Respect `SchemaDumper.ignore_tables` in rake tasks for databases structure dump
690
+ * Respect `SchemaDumper.ignore_tables` in rake tasks for databases structure dump.
632
691
 
633
692
  *Rusty Geldmacher*, *Guillermo Iguaran*
634
693
 
635
- * Add type caster to `RuntimeReflection#alias_name`
694
+ * Add type caster to `RuntimeReflection#alias_name`.
636
695
 
637
696
  Fixes #28959.
638
697
 
@@ -192,7 +192,7 @@ The latest version of Active Record can be installed with RubyGems:
192
192
 
193
193
  Source code can be downloaded as part of the Rails project on GitHub:
194
194
 
195
- * https://github.com/rails/rails/tree/master/activerecord
195
+ * https://github.com/rails/rails/tree/5-2-stable/activerecord
196
196
 
197
197
 
198
198
  == License
@@ -156,9 +156,9 @@ module ActiveRecord
156
156
  reset
157
157
  end
158
158
 
159
- # We can't dump @reflection since it contains the scope proc
159
+ # We can't dump @reflection and @through_reflection since it contains the scope proc
160
160
  def marshal_dump
161
- ivars = (instance_variables - [:@reflection]).map { |name| [name, instance_variable_get(name)] }
161
+ ivars = (instance_variables - [:@reflection, :@through_reflection]).map { |name| [name, instance_variable_get(name)] }
162
162
  [@reflection.name, ivars]
163
163
  end
164
164
 
@@ -201,8 +201,8 @@ module ActiveRecord
201
201
  if (reflection.has_one? || reflection.collection?) && !options[:through]
202
202
  attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
203
203
 
204
- if reflection.options[:as]
205
- attributes[reflection.type] = owner.class.base_class.name
204
+ if reflection.type
205
+ attributes[reflection.type] = owner.class.polymorphic_name
206
206
  end
207
207
  end
208
208
 
@@ -35,12 +35,12 @@ module ActiveRecord
35
35
 
36
36
  binds << last_reflection.join_id_for(owner)
37
37
  if last_reflection.type
38
- binds << owner.class.base_class.name
38
+ binds << owner.class.polymorphic_name
39
39
  end
40
40
 
41
41
  chain.each_cons(2).each do |reflection, next_reflection|
42
42
  if reflection.type
43
- binds << next_reflection.klass.base_class.name
43
+ binds << next_reflection.klass.polymorphic_name
44
44
  end
45
45
  end
46
46
  binds
@@ -67,7 +67,7 @@ module ActiveRecord
67
67
  scope = apply_scope(scope, table, key, value)
68
68
 
69
69
  if reflection.type
70
- polymorphic_type = transform_value(owner.class.base_class.name)
70
+ polymorphic_type = transform_value(owner.class.polymorphic_name)
71
71
  scope = apply_scope(scope, table, reflection.type, polymorphic_type)
72
72
  end
73
73
 
@@ -88,7 +88,7 @@ module ActiveRecord
88
88
  constraint = table[key].eq(foreign_table[foreign_key])
89
89
 
90
90
  if reflection.type
91
- value = transform_value(next_reflection.klass.base_class.name)
91
+ value = transform_value(next_reflection.klass.polymorphic_name)
92
92
  scope = apply_scope(scope, table, reflection.type, value)
93
93
  end
94
94
 
@@ -135,7 +135,7 @@ module ActiveRecord
135
135
  item = eval_scope(reflection, scope_chain_item, owner)
136
136
 
137
137
  if scope_chain_item == chain_head.scope
138
- scope.merge! item.except(:where, :includes)
138
+ scope.merge! item.except(:where, :includes, :unscope, :order)
139
139
  end
140
140
 
141
141
  reflection.all_includes do
@@ -144,7 +144,7 @@ module ActiveRecord
144
144
 
145
145
  scope.unscope!(*item.unscope_values)
146
146
  scope.where_clause += item.where_clause
147
- scope.order_values |= item.order_values
147
+ scope.order_values = item.order_values | scope.order_values
148
148
  end
149
149
  end
150
150
 
@@ -5,7 +5,15 @@ module ActiveRecord
5
5
  # = Active Record Belongs To Association
6
6
  class BelongsToAssociation < SingularAssociation #:nodoc:
7
7
  def handle_dependency
8
- target.send(options[:dependent]) if load_target
8
+ return unless load_target
9
+
10
+ case options[:dependent]
11
+ when :destroy
12
+ target.destroy
13
+ raise ActiveRecord::Rollback unless target.destroyed?
14
+ else
15
+ target.send(options[:dependent])
16
+ end
9
17
  end
10
18
 
11
19
  def replace(record)
@@ -13,7 +13,7 @@ module ActiveRecord
13
13
 
14
14
  def replace_keys(record)
15
15
  super
16
- owner[reflection.foreign_type] = record ? record.class.base_class.name : nil
16
+ owner[reflection.foreign_type] = record ? record.class.polymorphic_name : nil
17
17
  end
18
18
 
19
19
  def different_target?(record)
@@ -60,6 +60,7 @@ module ActiveRecord
60
60
  when :destroy
61
61
  target.destroyed_by_association = reflection
62
62
  target.destroy
63
+ throw(:abort) unless target.destroyed?
63
64
  when :nullify
64
65
  target.update_columns(reflection.foreign_key => nil) if target.persisted?
65
66
  end
@@ -88,9 +88,8 @@ module ActiveRecord
88
88
  # associations # => [:appointments]
89
89
  # joins # => []
90
90
  #
91
- def initialize(base, table, associations, alias_tracker, eager_loading: true)
91
+ def initialize(base, table, associations, alias_tracker)
92
92
  @alias_tracker = alias_tracker
93
- @eager_loading = eager_loading
94
93
  tree = self.class.make_tree associations
95
94
  @join_root = JoinBase.new(base, table, build(tree, base))
96
95
  @join_root.children.each { |child| construct_tables! @join_root, child }
@@ -221,12 +220,11 @@ module ActiveRecord
221
220
  reflection.check_eager_loadable!
222
221
 
223
222
  if reflection.polymorphic?
224
- next unless @eager_loading
225
223
  raise EagerLoadPolymorphicError.new(reflection)
226
224
  end
227
225
 
228
226
  JoinAssociation.new(reflection, build(right, reflection.klass), alias_tracker)
229
- end.compact
227
+ end
230
228
  end
231
229
 
232
230
  def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
@@ -118,7 +118,7 @@ module ActiveRecord
118
118
  scope = klass.scope_for_association
119
119
 
120
120
  if reflection.type
121
- scope.where!(reflection.type => model.base_class.sti_name)
121
+ scope.where!(reflection.type => model.polymorphic_name)
122
122
  end
123
123
 
124
124
  scope.merge!(reflection_scope) if reflection.scope
@@ -7,11 +7,6 @@ module ActiveRecord
7
7
  extend ActiveSupport::Concern
8
8
  include ActiveModel::AttributeAssignment
9
9
 
10
- # Alias for ActiveModel::AttributeAssignment#assign_attributes. See ActiveModel::AttributeAssignment.
11
- def attributes=(attributes)
12
- assign_attributes(attributes)
13
- end
14
-
15
10
  private
16
11
 
17
12
  def _assign_attributes(attributes)
@@ -175,9 +175,20 @@ module ActiveRecord
175
175
  # Regexp whitelist. Matches the following:
176
176
  # "#{table_name}.#{column_name}"
177
177
  # "#{table_name}.#{column_name} #{direction}"
178
+ # "#{table_name}.#{column_name} #{direction} NULLS FIRST"
179
+ # "#{table_name}.#{column_name} NULLS LAST"
178
180
  # "#{column_name}"
179
181
  # "#{column_name} #{direction}"
180
- COLUMN_NAME_ORDER_WHITELIST = /\A(?:\w+\.)?\w+(?:\s+asc|\s+desc)?\z/i
182
+ # "#{column_name} #{direction} NULLS FIRST"
183
+ # "#{column_name} NULLS LAST"
184
+ COLUMN_NAME_ORDER_WHITELIST = /
185
+ \A
186
+ (?:\w+\.)?
187
+ \w+
188
+ (?:\s+asc|\s+desc)?
189
+ (?:\s+nulls\s+(?:first|last))?
190
+ \z
191
+ /ix
181
192
 
182
193
  def enforce_raw_sql_whitelist(args, whitelist: COLUMN_NAME_WHITELIST) # :nodoc:
183
194
  unexpected = args.reject do |arg|
@@ -441,24 +452,18 @@ module ActiveRecord
441
452
 
442
453
  private
443
454
 
444
- def arel_attributes_with_values_for_create(attribute_names)
445
- arel_attributes_with_values(attributes_for_create(attribute_names))
455
+ def attributes_with_values_for_create(attribute_names)
456
+ attributes_with_values(attributes_for_create(attribute_names))
446
457
  end
447
458
 
448
- def arel_attributes_with_values_for_update(attribute_names)
449
- arel_attributes_with_values(attributes_for_update(attribute_names))
459
+ def attributes_with_values_for_update(attribute_names)
460
+ attributes_with_values(attributes_for_update(attribute_names))
450
461
  end
451
462
 
452
- # Returns a Hash of the Arel::Attributes and attribute values that have been
453
- # typecasted for use in an Arel insert/update method.
454
- def arel_attributes_with_values(attribute_names)
455
- attrs = {}
456
- arel_table = self.class.arel_table
457
-
458
- attribute_names.each do |name|
459
- attrs[arel_table[name]] = _read_attribute(name)
463
+ def attributes_with_values(attribute_names)
464
+ attribute_names.each_with_object({}) do |name, attrs|
465
+ attrs[name] = _read_attribute(name)
460
466
  end
461
- attrs
462
467
  end
463
468
 
464
469
  # Filters the primary keys and readonly attributes from the attribute names.
@@ -32,7 +32,9 @@ module ActiveRecord
32
32
  # <tt>reload</tt> the record and clears changed attributes.
33
33
  def reload(*)
34
34
  super.tap do
35
+ @previously_changed = ActiveSupport::HashWithIndifferentAccess.new
35
36
  @mutations_before_last_save = nil
37
+ @attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
36
38
  @mutations_from_database = nil
37
39
  end
38
40
  end
@@ -112,12 +114,12 @@ module ActiveRecord
112
114
 
113
115
  # Alias for +changed+
114
116
  def changed_attribute_names_to_save
115
- mutations_from_database.changed_attribute_names
117
+ changes_to_save.keys
116
118
  end
117
119
 
118
120
  # Alias for +changed_attributes+
119
121
  def attributes_in_database
120
- mutations_from_database.changed_values
122
+ changes_to_save.transform_values(&:first)
121
123
  end
122
124
 
123
125
  private
@@ -130,7 +130,7 @@ module ActiveRecord
130
130
  end
131
131
 
132
132
  def quoted_time(value) # :nodoc:
133
- quoted_date(value).sub(/\A2000-01-01 /, "")
133
+ quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
134
134
  end
135
135
 
136
136
  def quoted_binary(value) # :nodoc:
@@ -406,7 +406,7 @@ module ActiveRecord
406
406
  #
407
407
  # Defaults to false.
408
408
  #
409
- # Only supported on the MySQL adapter, ignored elsewhere.
409
+ # Only supported on the MySQL and PostgreSQL adapter, ignored elsewhere.
410
410
  #
411
411
  # ====== Add a column
412
412
  #