activerecord 6.0.0 → 6.0.3

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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +185 -1
  3. data/README.rdoc +1 -1
  4. data/lib/active_record.rb +1 -0
  5. data/lib/active_record/advisory_lock_base.rb +18 -0
  6. data/lib/active_record/aggregations.rb +0 -1
  7. data/lib/active_record/association_relation.rb +10 -8
  8. data/lib/active_record/associations.rb +2 -2
  9. data/lib/active_record/associations/alias_tracker.rb +0 -1
  10. data/lib/active_record/associations/association.rb +5 -1
  11. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -2
  12. data/lib/active_record/associations/collection_association.rb +6 -2
  13. data/lib/active_record/associations/collection_proxy.rb +1 -2
  14. data/lib/active_record/associations/has_many_association.rb +0 -1
  15. data/lib/active_record/associations/join_dependency.rb +13 -0
  16. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  17. data/lib/active_record/associations/preloader.rb +2 -3
  18. data/lib/active_record/attribute_assignment.rb +0 -1
  19. data/lib/active_record/attribute_decorators.rb +0 -2
  20. data/lib/active_record/attribute_methods/before_type_cast.rb +0 -1
  21. data/lib/active_record/attribute_methods/dirty.rb +2 -2
  22. data/lib/active_record/attribute_methods/primary_key.rb +0 -2
  23. data/lib/active_record/attribute_methods/read.rb +0 -1
  24. data/lib/active_record/attribute_methods/serialization.rb +0 -1
  25. data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -2
  26. data/lib/active_record/attribute_methods/write.rb +0 -1
  27. data/lib/active_record/attributes.rb +0 -1
  28. data/lib/active_record/autosave_association.rb +8 -6
  29. data/lib/active_record/callbacks.rb +1 -2
  30. data/lib/active_record/coders/yaml_column.rb +0 -1
  31. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +14 -7
  32. data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -15
  33. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -2
  34. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -2
  35. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +27 -27
  36. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +47 -30
  37. data/lib/active_record/connection_adapters/abstract/transaction.rb +4 -5
  38. data/lib/active_record/connection_adapters/abstract_adapter.rb +23 -8
  39. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -32
  40. data/lib/active_record/connection_adapters/connection_specification.rb +2 -3
  41. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  42. data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -12
  43. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
  44. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +1 -2
  45. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -8
  46. data/lib/active_record/connection_adapters/mysql2_adapter.rb +0 -1
  47. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +9 -3
  48. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
  49. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  50. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
  51. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +0 -1
  52. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  53. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +0 -1
  54. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +0 -1
  55. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  56. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +0 -1
  57. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  58. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -2
  59. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
  60. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  61. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -29
  62. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  63. data/lib/active_record/connection_adapters/postgresql_adapter.rb +9 -2
  64. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +8 -7
  65. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +0 -1
  66. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +3 -3
  67. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +12 -7
  68. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  69. data/lib/active_record/connection_handling.rb +13 -22
  70. data/lib/active_record/core.rb +8 -6
  71. data/lib/active_record/counter_cache.rb +4 -1
  72. data/lib/active_record/database_configurations/url_config.rb +0 -1
  73. data/lib/active_record/dynamic_matchers.rb +2 -3
  74. data/lib/active_record/explain.rb +0 -1
  75. data/lib/active_record/fixture_set/table_row.rb +0 -1
  76. data/lib/active_record/fixture_set/table_rows.rb +0 -1
  77. data/lib/active_record/fixtures.rb +0 -3
  78. data/lib/active_record/gem_version.rb +1 -1
  79. data/lib/active_record/inheritance.rb +0 -3
  80. data/lib/active_record/insert_all.rb +4 -4
  81. data/lib/active_record/internal_metadata.rb +1 -1
  82. data/lib/active_record/locking/optimistic.rb +0 -1
  83. data/lib/active_record/log_subscriber.rb +1 -1
  84. data/lib/active_record/middleware/database_selector.rb +0 -1
  85. data/lib/active_record/middleware/database_selector/resolver.rb +9 -14
  86. data/lib/active_record/migration.rb +4 -4
  87. data/lib/active_record/migration/command_recorder.rb +6 -18
  88. data/lib/active_record/migration/compatibility.rb +3 -3
  89. data/lib/active_record/migration/join_table.rb +0 -1
  90. data/lib/active_record/model_schema.rb +3 -2
  91. data/lib/active_record/nested_attributes.rb +0 -2
  92. data/lib/active_record/no_touching.rb +2 -2
  93. data/lib/active_record/null_relation.rb +0 -1
  94. data/lib/active_record/persistence.rb +4 -5
  95. data/lib/active_record/querying.rb +1 -1
  96. data/lib/active_record/railtie.rb +1 -1
  97. data/lib/active_record/railties/collection_cache_association_loading.rb +1 -1
  98. data/lib/active_record/railties/databases.rake +3 -0
  99. data/lib/active_record/reflection.rb +8 -8
  100. data/lib/active_record/relation.rb +13 -1
  101. data/lib/active_record/relation/batches.rb +0 -1
  102. data/lib/active_record/relation/calculations.rb +1 -1
  103. data/lib/active_record/relation/delegation.rb +7 -6
  104. data/lib/active_record/relation/finder_methods.rb +10 -2
  105. data/lib/active_record/relation/from_clause.rb +4 -0
  106. data/lib/active_record/relation/merger.rb +0 -1
  107. data/lib/active_record/relation/predicate_builder.rb +1 -5
  108. data/lib/active_record/relation/query_methods.rb +37 -12
  109. data/lib/active_record/relation/spawn_methods.rb +0 -1
  110. data/lib/active_record/relation/where_clause.rb +0 -1
  111. data/lib/active_record/result.rb +0 -1
  112. data/lib/active_record/schema_migration.rb +1 -1
  113. data/lib/active_record/scoping.rb +0 -1
  114. data/lib/active_record/scoping/default.rb +0 -1
  115. data/lib/active_record/scoping/named.rb +3 -3
  116. data/lib/active_record/store.rb +1 -1
  117. data/lib/active_record/suppressor.rb +2 -2
  118. data/lib/active_record/table_metadata.rb +16 -1
  119. data/lib/active_record/tasks/mysql_database_tasks.rb +0 -1
  120. data/lib/active_record/tasks/postgresql_database_tasks.rb +0 -1
  121. data/lib/active_record/tasks/sqlite_database_tasks.rb +0 -1
  122. data/lib/active_record/test_fixtures.rb +2 -1
  123. data/lib/active_record/timestamp.rb +0 -1
  124. data/lib/active_record/touch_later.rb +1 -2
  125. data/lib/active_record/transactions.rb +9 -9
  126. data/lib/active_record/type.rb +0 -1
  127. data/lib/active_record/type/adapter_specific_registry.rb +2 -5
  128. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  129. data/lib/active_record/type/serialized.rb +0 -1
  130. data/lib/active_record/type/type_map.rb +0 -1
  131. data/lib/active_record/type/unsigned_integer.rb +0 -1
  132. data/lib/active_record/validations.rb +2 -3
  133. data/lib/active_record/validations/associated.rb +1 -2
  134. data/lib/arel.rb +17 -6
  135. data/lib/arel/predications.rb +5 -6
  136. data/lib/arel/visitors/depth_first.rb +0 -1
  137. data/lib/arel/visitors/dot.rb +0 -1
  138. data/lib/arel/visitors/mssql.rb +0 -1
  139. data/lib/arel/visitors/oracle.rb +1 -2
  140. data/lib/arel/visitors/oracle12.rb +0 -1
  141. data/lib/arel/visitors/postgresql.rb +0 -1
  142. data/lib/arel/visitors/sqlite.rb +0 -1
  143. data/lib/arel/visitors/to_sql.rb +0 -1
  144. data/lib/arel/visitors/visitor.rb +0 -1
  145. data/lib/arel/visitors/where_sql.rb +0 -1
  146. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  147. data/lib/rails/generators/active_record/migration.rb +0 -1
  148. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +1 -1
  149. data/lib/rails/generators/active_record/model/model_generator.rb +0 -1
  150. metadata +13 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed17e948626d108075b2951ac71abbac3075ef55b055abe64e2b352e91755fd9
4
- data.tar.gz: 2c031642e021041f9fdf278888b580fd446879008a23f12d33c8b33aafbddc59
3
+ metadata.gz: d8ac16c2194f2d74297c1fdbfd64c286003ce2aea666afd85bfa07ecac816877
4
+ data.tar.gz: a15e33a862b0985aea1d3b506ce53dd38678c3f47a121dddcd5c90388665788e
5
5
  SHA512:
6
- metadata.gz: 6b208a5cbee77c2a057649b762a92ec4ca5be3b8fbd1b2123caf485579abbc602bcb2aee455a503b74f33efa9ce364ab644dc8958b9e1edd94fee3397bf17cc8
7
- data.tar.gz: 751ecf72279d478887665f6a3efc5ad366b70284fb3f4ef6d2f3b072faf7c325be660116a7d3ac9427ac44dcf6f8c345e145921692d0465e24a70f1c2ca3b1bd
6
+ metadata.gz: be693dc74628ffedf85fe5dd569b2bec88e1ccd1b3ed61a347ce63f612747c8e50485d41d46a70fd803f8fbc454572592e59bea246152c0902057ef5c384a235
7
+ data.tar.gz: 33294c99f5631c31762075cfb88da12fb106794f4a68d28d227fb177d92fe1afd832148331b9ba273f338fa749d1a3679cffaafef464549f79292e2de8b08e08
@@ -1,3 +1,187 @@
1
+ ## Rails 6.0.3 (May 06, 2020) ##
2
+
3
+ * Recommend applications don't use the `database` kwarg in `connected_to`
4
+
5
+ The database kwarg in `connected_to` was meant to be used for one-off scripts but is often used in requests. This is really dangerous because it re-establishes a connection every time. It's deprecated in 6.1 and will be removed in 6.2 without replacement. This change soft deprecates it in 6.0 by removing documentation.
6
+
7
+ *Eileen M. Uchitelle*
8
+
9
+ * Fix support for PostgreSQL 11+ partitioned indexes.
10
+
11
+ *Sebastián Palma*
12
+
13
+ * Add support for beginless ranges, introduced in Ruby 2.7.
14
+
15
+ *Josh Goodall*
16
+
17
+ * Fix insert_all with enum values
18
+
19
+ Fixes #38716.
20
+
21
+ *Joel Blum*
22
+
23
+ * Regexp-escape table name for MS SQL
24
+
25
+ Add `Regexp.escape` to one method in ActiveRecord, so that table names with regular expression characters in them work as expected. Since MS SQL Server uses "[" and "]" to quote table and column names, and those characters are regular expression characters, methods like `pluck` and `select` fail in certain cases when used with the MS SQL Server adapter.
26
+
27
+ *Larry Reid*
28
+
29
+ * Store advisory locks on their own named connection.
30
+
31
+ Previously advisory locks were taken out against a connection when a migration started. This works fine in single database applications but doesn't work well when migrations need to open new connections which results in the lock getting dropped.
32
+
33
+ In order to fix this we are storing the advisory lock on a new connection with the connection specification name `AdisoryLockBase`. The caveat is that we need to maintain at least 2 connections to a database while migrations are running in order to do this.
34
+
35
+ *Eileen M. Uchitelle*, *John Crepezzi*
36
+
37
+ * Ensure `:reading` connections always raise if a write is attempted.
38
+
39
+ Now Rails will raise an `ActiveRecord::ReadOnlyError` if any connection on the reading handler attempts to make a write. If your reading role needs to write you should name the role something other than `:reading`.
40
+
41
+ *Eileen M. Uchitelle*
42
+
43
+ * Enforce fresh ETag header after a collection's contents change by adding
44
+ ActiveRecord::Relation#cache_key_with_version. This method will be used by
45
+ ActionController::ConditionalGet to ensure that when collection cache versioning
46
+ is enabled, requests using ConditionalGet don't return the same ETag header
47
+ after a collection is modified. Fixes #38078.
48
+
49
+ *Aaron Lipman*
50
+
51
+ * A database URL can now contain a querystring value that contains an equal sign. This is needed to support passing PostgresSQL `options`.
52
+
53
+ *Joshua Flanagan*
54
+
55
+ * Retain explicit selections on the base model after applying `includes` and `joins`.
56
+
57
+ Resolves #34889.
58
+
59
+ *Patrick Rebsch*
60
+
61
+
62
+ ## Rails 6.0.2.2 (March 19, 2020) ##
63
+
64
+ * No changes.
65
+
66
+
67
+ ## Rails 6.0.2.1 (December 18, 2019) ##
68
+
69
+ * No changes.
70
+
71
+
72
+ ## Rails 6.0.2 (December 13, 2019) ##
73
+
74
+ * Share the same connection pool for primary and replica databases in the
75
+ transactional tests for the same database.
76
+
77
+ *Edouard Chin*
78
+
79
+ * Fix the preloader when one record is fetched using `after_initialize`
80
+ but not the entire collection.
81
+
82
+ *Bradley Price*
83
+
84
+ * Fix collection callbacks not terminating when `:abort` is thrown.
85
+
86
+ *Edouard Chin*, *Ryuta Kamizono*
87
+
88
+ * Correctly deprecate `where.not` working as NOR for relations.
89
+
90
+ 12a9664 deprecated where.not working as NOR, however
91
+ doing a relation query like `where.not(relation: { ... })`
92
+ wouldn't be properly deprecated and `where.not` would work as
93
+ NAND instead.
94
+
95
+ *Edouard Chin*
96
+
97
+ * Fix `db:migrate` task with multiple databases to restore the connection
98
+ to the previous database.
99
+
100
+ The migrate task iterates and establish a connection over each db
101
+ resulting in the last one to be used by subsequent rake tasks.
102
+ We should reestablish a connection to the connection that was
103
+ established before the migrate tasks was run
104
+
105
+ *Edouard Chin*
106
+
107
+ * Fix multi-threaded issue for `AcceptanceValidator`.
108
+
109
+ *Ryuta Kamizono*
110
+
111
+
112
+ ## Rails 6.0.1 (November 5, 2019) ##
113
+
114
+ * Common Table Expressions are allowed on read-only connections.
115
+
116
+ *Chris Morris*
117
+
118
+ * New record instantiation respects `unscope`.
119
+
120
+ *Ryuta Kamizono*
121
+
122
+ * Fixed a case where `find_in_batches` could halt too early.
123
+
124
+ *Takayuki Nakata*
125
+
126
+ * Autosaved associations always perform validations when a custom validation
127
+ context is used.
128
+
129
+ *Tekin Suleyman*
130
+
131
+ * `sql.active_record` notifications now include the `:connection` in
132
+ their payloads.
133
+
134
+ *Eugene Kenny*
135
+
136
+ * A rollback encountered in an `after_commit` callback does not reset
137
+ previously-committed record state.
138
+
139
+ *Ryuta Kamizono*
140
+
141
+ * Fixed that join order was lost when eager-loading.
142
+
143
+ *Ryuta Kamizono*
144
+
145
+ * `DESCRIBE` queries are allowed on read-only connections.
146
+
147
+ *Dylan Thacker-Smith*
148
+
149
+ * Fixed that records that had been `inspect`ed could not be marshaled.
150
+
151
+ *Eugene Kenny*
152
+
153
+ * The connection pool reaper thread is respawned in forked processes. This
154
+ fixes that idle connections in forked processes wouldn't be reaped.
155
+
156
+ *John Hawthorn*
157
+
158
+ * The memoized result of `ActiveRecord::Relation#take` is properly cleared
159
+ when `ActiveRecord::Relation#reset` or `ActiveRecord::Relation#reload`
160
+ is called.
161
+
162
+ *Anmol Arora*
163
+
164
+ * Fixed the performance regression for `primary_keys` introduced MySQL 8.0.
165
+
166
+ *Hiroyuki Ishii*
167
+
168
+ * `insert`, `insert_all`, `upsert`, and `upsert_all` now clear the query cache.
169
+
170
+ *Eugene Kenny*
171
+
172
+ * Call `while_preventing_writes` directly from `connected_to`.
173
+
174
+ In some cases application authors want to use the database switching middleware and make explicit calls with `connected_to`. It's possible for an app to turn off writes and not turn them back on by the time we call `connected_to(role: :writing)`.
175
+
176
+ This change allows apps to fix this by assuming if a role is writing we want to allow writes, except in the case it's explicitly turned off.
177
+
178
+ *Eileen M. Uchitelle*
179
+
180
+ * Improve detection of ActiveRecord::StatementTimeout with mysql2 adapter in the edge case when the query is terminated during filesort.
181
+
182
+ *Kir Shatrov*
183
+
184
+
1
185
  ## Rails 6.0.0 (August 16, 2019) ##
2
186
 
3
187
  * Preserve user supplied joins order as much as possible.
@@ -478,7 +662,7 @@
478
662
 
479
663
  *Rafael Mendonça França*
480
664
 
481
- * Deprecate `config.activerecord.sqlite3.represent_boolean_as_integer`.
665
+ * Deprecate `config.active_record.sqlite3.represent_boolean_as_integer`.
482
666
 
483
667
  *Rafael Mendonça França*
484
668
 
@@ -216,4 +216,4 @@ Bug reports for the Ruby on Rails project can be filed here:
216
216
 
217
217
  Feature requests should be discussed on the rails-core mailing list here:
218
218
 
219
- * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
219
+ * https://discuss.rubyonrails.org/c/rubyonrails-core
@@ -35,6 +35,7 @@ require "active_model/attribute_set"
35
35
  module ActiveRecord
36
36
  extend ActiveSupport::Autoload
37
37
 
38
+ autoload :AdvisoryLockBase
38
39
  autoload :Base
39
40
  autoload :Callbacks
40
41
  autoload :Core
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ # This class is used to create a connection that we can use for advisory
5
+ # locks. This will take out a "global" lock that can't be accidentally
6
+ # removed if a new connection is established during a migration.
7
+ class AdvisoryLockBase < ActiveRecord::Base # :nodoc:
8
+ self.abstract_class = true
9
+
10
+ self.connection_specification_name = "AdvisoryLockBase"
11
+
12
+ class << self
13
+ def _internal?
14
+ true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -14,7 +14,6 @@ module ActiveRecord
14
14
  end
15
15
 
16
16
  private
17
-
18
17
  def clear_aggregation_cache
19
18
  @aggregation_cache.clear if persisted?
20
19
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveRecord
4
4
  class AssociationRelation < Relation
5
- def initialize(klass, association)
5
+ def initialize(klass, association, **)
6
6
  super(klass)
7
7
  @association = association
8
8
  end
@@ -15,21 +15,23 @@ module ActiveRecord
15
15
  other == records
16
16
  end
17
17
 
18
- def build(*args, &block)
19
- scoping { @association.build(*args, &block) }
18
+ def build(attributes = nil, &block)
19
+ block = _deprecated_scope_block("new", &block)
20
+ scoping { @association.build(attributes, &block) }
20
21
  end
21
22
  alias new build
22
23
 
23
- def create(*args, &block)
24
- scoping { @association.create(*args, &block) }
24
+ def create(attributes = nil, &block)
25
+ block = _deprecated_scope_block("create", &block)
26
+ scoping { @association.create(attributes, &block) }
25
27
  end
26
28
 
27
- def create!(*args, &block)
28
- scoping { @association.create!(*args, &block) }
29
+ def create!(attributes = nil, &block)
30
+ block = _deprecated_scope_block("create!", &block)
31
+ scoping { @association.create!(attributes, &block) }
29
32
  end
30
33
 
31
34
  private
32
-
33
35
  def exec_queries
34
36
  super do |record|
35
37
  @association.set_inverse_instance_from_queries(record)
@@ -92,7 +92,7 @@ module ActiveRecord
92
92
  through_reflection = reflection.through_reflection
93
93
  source_reflection_names = reflection.source_reflection_names
94
94
  source_associations = reflection.through_reflection.klass._reflections.keys
95
- super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ', locale: :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ', locale: :en)}?")
95
+ super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')}?")
96
96
  else
97
97
  super("Could not find the source association(s).")
98
98
  end
@@ -1857,7 +1857,7 @@ module ActiveRecord
1857
1857
  hm_options[k] = options[k] if options.key? k
1858
1858
  end
1859
1859
 
1860
- has_many name, scope, hm_options, &extension
1860
+ has_many name, scope, **hm_options, &extension
1861
1861
  _reflections[name.to_s].parent_reflection = habtm_reflection
1862
1862
  end
1863
1863
  end
@@ -72,7 +72,6 @@ module ActiveRecord
72
72
  attr_reader :aliases
73
73
 
74
74
  private
75
-
76
75
  def truncate(name)
77
76
  name.slice(0, @connection.table_alias_length - 2)
78
77
  end
@@ -95,7 +95,11 @@ module ActiveRecord
95
95
  end
96
96
 
97
97
  def scope
98
- target_scope.merge!(association_scope)
98
+ if (scope = klass.current_scope) && scope.try(:proxy_association) == self
99
+ scope.spawn
100
+ else
101
+ target_scope.merge!(association_scope)
102
+ end
99
103
  end
100
104
 
101
105
  def reset_scope
@@ -46,7 +46,6 @@ module ActiveRecord::Associations::Builder # :nodoc:
46
46
  end
47
47
 
48
48
  private
49
-
50
49
  def self.suppress_composite_primary_key(pk)
51
50
  pk unless pk.is_a?(Array)
52
51
  end
@@ -73,7 +72,6 @@ module ActiveRecord::Associations::Builder # :nodoc:
73
72
  end
74
73
 
75
74
  private
76
-
77
75
  def middle_options(join_model)
78
76
  middle_options = {}
79
77
  middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}"
@@ -378,7 +378,9 @@ module ActiveRecord
378
378
  end
379
379
 
380
380
  def remove_records(existing_records, records, method)
381
- records.each { |record| callback(:before_remove, record) }
381
+ catch(:abort) do
382
+ records.each { |record| callback(:before_remove, record) }
383
+ end || return
382
384
 
383
385
  delete_records(existing_records, method) if existing_records.any?
384
386
  @target -= records
@@ -434,7 +436,9 @@ module ActiveRecord
434
436
  end
435
437
 
436
438
  def replace_on_target(record, index, skip_callbacks)
437
- callback(:before_add, record) unless skip_callbacks
439
+ catch(:abort) do
440
+ callback(:before_add, record)
441
+ end || return unless skip_callbacks
438
442
 
439
443
  set_inverse_instance(record)
440
444
 
@@ -27,7 +27,7 @@ module ActiveRecord
27
27
  # is computed directly through SQL and does not trigger by itself the
28
28
  # instantiation of the actual post records.
29
29
  class CollectionProxy < Relation
30
- def initialize(klass, association) #:nodoc:
30
+ def initialize(klass, association, **) #:nodoc:
31
31
  @association = association
32
32
  super klass
33
33
 
@@ -1101,7 +1101,6 @@ module ActiveRecord
1101
1101
  delegate(*delegate_methods, to: :scope)
1102
1102
 
1103
1103
  private
1104
-
1105
1104
  def find_nth_with_limit(index, limit)
1106
1105
  load_target if find_from_target?
1107
1106
  super
@@ -37,7 +37,6 @@ module ActiveRecord
37
37
  end
38
38
 
39
39
  private
40
-
41
40
  # Returns the number of records in this collection.
42
41
  #
43
42
  # If the association has a counter cache it gets that value. Otherwise
@@ -70,6 +70,10 @@ module ActiveRecord
70
70
  @join_type = join_type
71
71
  end
72
72
 
73
+ def base_klass
74
+ join_root.base_klass
75
+ end
76
+
73
77
  def reflections
74
78
  join_root.drop(1).map!(&:reflection)
75
79
  end
@@ -101,7 +105,9 @@ module ActiveRecord
101
105
 
102
106
  model_cache = Hash.new { |h, klass| h[klass] = {} }
103
107
  parents = model_cache[join_root]
108
+
104
109
  column_aliases = aliases.column_aliases join_root
110
+ column_aliases += explicit_selections(column_aliases, result_set)
105
111
 
106
112
  message_bus = ActiveSupport::Notifications.instrumenter
107
113
 
@@ -131,6 +137,13 @@ module ActiveRecord
131
137
  private
132
138
  attr_reader :alias_tracker
133
139
 
140
+ def explicit_selections(root_column_aliases, result_set)
141
+ root_names = root_column_aliases.map(&:name).to_set
142
+ result_set.columns
143
+ .reject { |n| root_names.include?(n) || n =~ /\At\d+_r\d+\z/ }
144
+ .map { |n| Aliases::Column.new(n, n) }
145
+ end
146
+
134
147
  def aliases
135
148
  @aliases ||= Aliases.new join_root.each_with_index.map { |join_part, i|
136
149
  columns = join_part.column_names.each_with_index.map { |column_name, j|
@@ -37,7 +37,7 @@ module ActiveRecord
37
37
  nodes = arel.constraints.first
38
38
 
39
39
  others = nodes.children.extract! do |node|
40
- Arel.fetch_attribute(node) { |attr| attr.relation.name != table.name }
40
+ !Arel.fetch_attribute(node) { |attr| attr.relation.name == table.name }
41
41
  end
42
42
 
43
43
  joins << table.create_join(table, table.create_on(nodes), join_type)
@@ -95,7 +95,6 @@ module ActiveRecord
95
95
  end
96
96
 
97
97
  private
98
-
99
98
  # Loads all the given data into +records+ for the +association+.
100
99
  def preloaders_on(association, records, scope, polymorphic_parent = false)
101
100
  case association
@@ -112,7 +111,7 @@ module ActiveRecord
112
111
  association.flat_map { |parent, child|
113
112
  grouped_records(parent, records, polymorphic_parent).flat_map do |reflection, reflection_records|
114
113
  loaders = preloaders_for_reflection(reflection, reflection_records, scope)
115
- recs = loaders.flat_map(&:preloaded_records)
114
+ recs = loaders.flat_map(&:preloaded_records).uniq
116
115
  child_polymorphic_parent = reflection && reflection.options[:polymorphic]
117
116
  loaders.concat Array.wrap(child).flat_map { |assoc|
118
117
  preloaders_on assoc, recs, scope, child_polymorphic_parent
@@ -185,7 +184,7 @@ module ActiveRecord
185
184
  # and attach it to a relation. The class returned implements a `run` method
186
185
  # that accepts a preloader.
187
186
  def preloader_for(reflection, owners)
188
- if owners.first.association(reflection.name).loaded?
187
+ if owners.all? { |o| o.association(reflection.name).loaded? }
189
188
  return AlreadyLoaded
190
189
  end
191
190
  reflection.check_preloadable!