activerecord 7.2.0.beta2 → 7.2.0.beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -1
- data/lib/active_record/associations/collection_association.rb +3 -3
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations.rb +0 -262
- data/lib/active_record/attribute_methods/dirty.rb +1 -1
- data/lib/active_record/attribute_methods/read.rb +3 -3
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +8 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +27 -11
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/transaction.rb +67 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +8 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1 -1
- data/lib/active_record/database_configurations/database_config.rb +4 -0
- data/lib/active_record/errors.rb +20 -8
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/railtie.rb +2 -3
- data/lib/active_record/railties/databases.rake +1 -1
- data/lib/active_record/relation/calculations.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +21 -9
- data/lib/active_record/signed_id.rb +9 -0
- data/lib/active_record/test_fixtures.rb +10 -3
- data/lib/active_record/timestamp.rb +1 -1
- data/lib/active_record/transaction.rb +56 -55
- data/lib/active_record/transactions.rb +1 -1
- data/lib/active_record.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a80eeb42f7130f9c9b8f9b9980959b202c550f1cf958326ffb3364161435b5f
|
4
|
+
data.tar.gz: b875a8e003cfce381c29733acf6c3f019ffed72a52a1f01be123913294ea31de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0eb8b60fa9d521a514799b6e5f5a5d1adaac422270b20245849ade043cd45aa485d0a17b57d163c641bc3ae29fa5700dbfa11c55451858de0d0b1647a97a666b
|
7
|
+
data.tar.gz: 68f46c24553e6c1f85751aa223a53e186abd1ec8a744e3803709552e33bbe757193498141af13b918646bc83b1bcb83bee5a2e58f3f1278d785e54a3c444ca32
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
## Rails 7.2.0.beta3 (July 11, 2024) ##
|
2
|
+
|
3
|
+
* Add condensed `#inspect` for `ConnectionPool`, `AbstractAdapter`, and
|
4
|
+
`DatabaseConfig`.
|
5
|
+
|
6
|
+
*Hartley McGuire*
|
7
|
+
|
8
|
+
* Fixed a memory performance issue in Active Record attribute methods definition.
|
9
|
+
|
10
|
+
*Jean Boussier*
|
11
|
+
|
12
|
+
* Define the new Active Support notification event `start_transaction.active_record`.
|
13
|
+
|
14
|
+
This event is fired when database transactions or savepoints start, and
|
15
|
+
complements `transaction.active_record`, which is emitted when they finish.
|
16
|
+
|
17
|
+
The payload has the transaction (`:transaction`) and the connection (`:connection`).
|
18
|
+
|
19
|
+
*Xavier Noria*
|
20
|
+
|
21
|
+
* Fix an issue where the IDs reader method did not return expected results
|
22
|
+
for preloaded associations in models using composite primary keys.
|
23
|
+
|
24
|
+
*Jay Ang*
|
25
|
+
|
26
|
+
|
1
27
|
## Rails 7.2.0.beta2 (June 04, 2024) ##
|
2
28
|
|
3
29
|
* The payload of `sql.active_record` Active Support notifications now has the current transaction in the `:transaction` key.
|
@@ -12,6 +38,7 @@
|
|
12
38
|
|
13
39
|
*Xavier Noria*
|
14
40
|
|
41
|
+
|
15
42
|
## Rails 7.2.0.beta1 (May 29, 2024) ##
|
16
43
|
|
17
44
|
* Fix inference of association model on nested models with the same demodularized name.
|
@@ -407,7 +434,7 @@
|
|
407
434
|
|
408
435
|
*Rafael Mendonça França*
|
409
436
|
|
410
|
-
* Remove deprecated `ActiveRecord::Migration.check_pending
|
437
|
+
* Remove deprecated `ActiveRecord::Migration.check_pending!` method.
|
411
438
|
|
412
439
|
*Rafael Mendonça França*
|
413
440
|
|
@@ -50,11 +50,11 @@ module ActiveRecord
|
|
50
50
|
# Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
|
51
51
|
def ids_reader
|
52
52
|
if loaded?
|
53
|
-
target.pluck(reflection.association_primary_key)
|
53
|
+
target.pluck(*reflection.association_primary_key)
|
54
54
|
elsif !target.empty?
|
55
|
-
load_target.pluck(reflection.association_primary_key)
|
55
|
+
load_target.pluck(*reflection.association_primary_key)
|
56
56
|
else
|
57
|
-
@association_ids ||= scope.pluck(reflection.association_primary_key)
|
57
|
+
@association_ids ||= scope.pluck(*reflection.association_primary_key)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -0,0 +1,265 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class AssociationNotFoundError < ConfigurationError # :nodoc:
|
5
|
+
attr_reader :record, :association_name
|
6
|
+
|
7
|
+
def initialize(record = nil, association_name = nil)
|
8
|
+
@record = record
|
9
|
+
@association_name = association_name
|
10
|
+
if record && association_name
|
11
|
+
super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
|
12
|
+
else
|
13
|
+
super("Association was not found.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
18
|
+
include DidYouMean::Correctable
|
19
|
+
|
20
|
+
def corrections
|
21
|
+
if record && association_name
|
22
|
+
@corrections ||= begin
|
23
|
+
maybe_these = record.class.reflections.keys
|
24
|
+
DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(association_name)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
[]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class InverseOfAssociationNotFoundError < ActiveRecordError # :nodoc:
|
34
|
+
attr_reader :reflection, :associated_class
|
35
|
+
|
36
|
+
def initialize(reflection = nil, associated_class = nil)
|
37
|
+
if reflection
|
38
|
+
@reflection = reflection
|
39
|
+
@associated_class = associated_class.nil? ? reflection.klass : associated_class
|
40
|
+
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
|
41
|
+
else
|
42
|
+
super("Could not find the inverse association.")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
47
|
+
include DidYouMean::Correctable
|
48
|
+
|
49
|
+
def corrections
|
50
|
+
if reflection && associated_class
|
51
|
+
@corrections ||= begin
|
52
|
+
maybe_these = associated_class.reflections.keys
|
53
|
+
DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:inverse_of].to_s)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
[]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class InverseOfAssociationRecursiveError < ActiveRecordError # :nodoc:
|
63
|
+
attr_reader :reflection
|
64
|
+
def initialize(reflection = nil)
|
65
|
+
if reflection
|
66
|
+
@reflection = reflection
|
67
|
+
super("Inverse association #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{reflection.class_name}) is recursive.")
|
68
|
+
else
|
69
|
+
super("Inverse association is recursive.")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class HasManyThroughAssociationNotFoundError < ActiveRecordError # :nodoc:
|
75
|
+
attr_reader :owner_class, :reflection
|
76
|
+
|
77
|
+
def initialize(owner_class = nil, reflection = nil)
|
78
|
+
if owner_class && reflection
|
79
|
+
@owner_class = owner_class
|
80
|
+
@reflection = reflection
|
81
|
+
super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class.name}")
|
82
|
+
else
|
83
|
+
super("Could not find the association.")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
88
|
+
include DidYouMean::Correctable
|
89
|
+
|
90
|
+
def corrections
|
91
|
+
if owner_class && reflection
|
92
|
+
@corrections ||= begin
|
93
|
+
maybe_these = owner_class.reflections.keys
|
94
|
+
maybe_these -= [reflection.name.to_s] # remove failing reflection
|
95
|
+
DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:through].to_s)
|
96
|
+
end
|
97
|
+
else
|
98
|
+
[]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError # :nodoc:
|
105
|
+
def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
|
106
|
+
if owner_class_name && reflection && source_reflection
|
107
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
|
108
|
+
else
|
109
|
+
super("Cannot have a has_many :through association.")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
|
115
|
+
def initialize(owner_class_name = nil, reflection = nil)
|
116
|
+
if owner_class_name && reflection
|
117
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
|
118
|
+
else
|
119
|
+
super("Cannot have a has_many :through association.")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError # :nodoc:
|
125
|
+
def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
|
126
|
+
if owner_class_name && reflection && source_reflection
|
127
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
|
128
|
+
else
|
129
|
+
super("Cannot have a has_many :through association.")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class HasOneThroughCantAssociateThroughCollection < ActiveRecordError # :nodoc:
|
135
|
+
def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
|
136
|
+
if owner_class_name && reflection && through_reflection
|
137
|
+
super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
|
138
|
+
else
|
139
|
+
super("Cannot have a has_one :through association.")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class HasOneAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
|
145
|
+
def initialize(owner_class_name = nil, reflection = nil)
|
146
|
+
if owner_class_name && reflection
|
147
|
+
super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
|
148
|
+
else
|
149
|
+
super("Cannot have a has_one :through association.")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError # :nodoc:
|
155
|
+
def initialize(reflection = nil)
|
156
|
+
if reflection
|
157
|
+
through_reflection = reflection.through_reflection
|
158
|
+
source_reflection_names = reflection.source_reflection_names
|
159
|
+
source_associations = reflection.through_reflection.klass._reflections.keys
|
160
|
+
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 ')}?")
|
161
|
+
else
|
162
|
+
super("Could not find the source association(s).")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class HasManyThroughOrderError < ActiveRecordError # :nodoc:
|
168
|
+
def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
|
169
|
+
if owner_class_name && reflection && through_reflection
|
170
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through '#{owner_class_name}##{through_reflection.name}' before the through association is defined.")
|
171
|
+
else
|
172
|
+
super("Cannot have a has_many :through association before the through association is defined.")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError # :nodoc:
|
178
|
+
def initialize(owner = nil, reflection = nil)
|
179
|
+
if owner && reflection
|
180
|
+
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
|
181
|
+
else
|
182
|
+
super("Cannot modify association.")
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class CompositePrimaryKeyMismatchError < ActiveRecordError # :nodoc:
|
188
|
+
attr_reader :reflection
|
189
|
+
|
190
|
+
def initialize(reflection = nil)
|
191
|
+
if reflection
|
192
|
+
if reflection.has_one? || reflection.collection?
|
193
|
+
super("Association #{reflection.active_record}##{reflection.name} primary key #{reflection.active_record_primary_key} doesn't match with foreign key #{reflection.foreign_key}. Please specify query_constraints, or primary_key and foreign_key values.")
|
194
|
+
else
|
195
|
+
super("Association #{reflection.active_record}##{reflection.name} primary key #{reflection.association_primary_key} doesn't match with foreign key #{reflection.foreign_key}. Please specify query_constraints, or primary_key and foreign_key values.")
|
196
|
+
end
|
197
|
+
else
|
198
|
+
super("Association primary key doesn't match with foreign key.")
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class AmbiguousSourceReflectionForThroughAssociation < ActiveRecordError # :nodoc:
|
204
|
+
def initialize(klass, macro, association_name, options, possible_sources)
|
205
|
+
example_options = options.dup
|
206
|
+
example_options[:source] = possible_sources.first
|
207
|
+
|
208
|
+
super("Ambiguous source reflection for through association. Please " \
|
209
|
+
"specify a :source directive on your declaration like:\n" \
|
210
|
+
"\n" \
|
211
|
+
" class #{klass} < ActiveRecord::Base\n" \
|
212
|
+
" #{macro} :#{association_name}, #{example_options}\n" \
|
213
|
+
" end"
|
214
|
+
)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
|
219
|
+
end
|
220
|
+
|
221
|
+
class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
|
222
|
+
end
|
223
|
+
|
224
|
+
class ThroughNestedAssociationsAreReadonly < ActiveRecordError # :nodoc:
|
225
|
+
def initialize(owner = nil, reflection = nil)
|
226
|
+
if owner && reflection
|
227
|
+
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
|
228
|
+
else
|
229
|
+
super("Through nested associations are read-only.")
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
|
235
|
+
end
|
236
|
+
|
237
|
+
class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
|
238
|
+
end
|
239
|
+
|
240
|
+
# This error is raised when trying to eager load a polymorphic association using a JOIN.
|
241
|
+
# Eager loading polymorphic associations is only possible with
|
242
|
+
# {ActiveRecord::Relation#preload}[rdoc-ref:QueryMethods#preload].
|
243
|
+
class EagerLoadPolymorphicError < ActiveRecordError
|
244
|
+
def initialize(reflection = nil)
|
245
|
+
if reflection
|
246
|
+
super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
|
247
|
+
else
|
248
|
+
super("Eager load polymorphic error.")
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
# This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
|
254
|
+
# (has_many, has_one) when there is at least 1 child associated instance.
|
255
|
+
# ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
|
256
|
+
class DeleteRestrictionError < ActiveRecordError # :nodoc:
|
257
|
+
def initialize(name = nil)
|
258
|
+
if name
|
259
|
+
super("Cannot delete record because of dependent #{name}")
|
260
|
+
else
|
261
|
+
super("Delete restriction error.")
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
@@ -1,268 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
|
-
class AssociationNotFoundError < ConfigurationError # :nodoc:
|
5
|
-
attr_reader :record, :association_name
|
6
|
-
|
7
|
-
def initialize(record = nil, association_name = nil)
|
8
|
-
@record = record
|
9
|
-
@association_name = association_name
|
10
|
-
if record && association_name
|
11
|
-
super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
|
12
|
-
else
|
13
|
-
super("Association was not found.")
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
18
|
-
include DidYouMean::Correctable
|
19
|
-
|
20
|
-
def corrections
|
21
|
-
if record && association_name
|
22
|
-
@corrections ||= begin
|
23
|
-
maybe_these = record.class.reflections.keys
|
24
|
-
DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(association_name)
|
25
|
-
end
|
26
|
-
else
|
27
|
-
[]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class InverseOfAssociationNotFoundError < ActiveRecordError # :nodoc:
|
34
|
-
attr_reader :reflection, :associated_class
|
35
|
-
|
36
|
-
def initialize(reflection = nil, associated_class = nil)
|
37
|
-
if reflection
|
38
|
-
@reflection = reflection
|
39
|
-
@associated_class = associated_class.nil? ? reflection.klass : associated_class
|
40
|
-
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
|
41
|
-
else
|
42
|
-
super("Could not find the inverse association.")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
47
|
-
include DidYouMean::Correctable
|
48
|
-
|
49
|
-
def corrections
|
50
|
-
if reflection && associated_class
|
51
|
-
@corrections ||= begin
|
52
|
-
maybe_these = associated_class.reflections.keys
|
53
|
-
DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:inverse_of].to_s)
|
54
|
-
end
|
55
|
-
else
|
56
|
-
[]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
class InverseOfAssociationRecursiveError < ActiveRecordError # :nodoc:
|
63
|
-
attr_reader :reflection
|
64
|
-
def initialize(reflection = nil)
|
65
|
-
if reflection
|
66
|
-
@reflection = reflection
|
67
|
-
super("Inverse association #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{reflection.class_name}) is recursive.")
|
68
|
-
else
|
69
|
-
super("Inverse association is recursive.")
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class HasManyThroughAssociationNotFoundError < ActiveRecordError # :nodoc:
|
75
|
-
attr_reader :owner_class, :reflection
|
76
|
-
|
77
|
-
def initialize(owner_class = nil, reflection = nil)
|
78
|
-
if owner_class && reflection
|
79
|
-
@owner_class = owner_class
|
80
|
-
@reflection = reflection
|
81
|
-
super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class.name}")
|
82
|
-
else
|
83
|
-
super("Could not find the association.")
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
|
88
|
-
include DidYouMean::Correctable
|
89
|
-
|
90
|
-
def corrections
|
91
|
-
if owner_class && reflection
|
92
|
-
@corrections ||= begin
|
93
|
-
maybe_these = owner_class.reflections.keys
|
94
|
-
maybe_these -= [reflection.name.to_s] # remove failing reflection
|
95
|
-
DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:through].to_s)
|
96
|
-
end
|
97
|
-
else
|
98
|
-
[]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError # :nodoc:
|
105
|
-
def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
|
106
|
-
if owner_class_name && reflection && source_reflection
|
107
|
-
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
|
108
|
-
else
|
109
|
-
super("Cannot have a has_many :through association.")
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
|
115
|
-
def initialize(owner_class_name = nil, reflection = nil)
|
116
|
-
if owner_class_name && reflection
|
117
|
-
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
|
118
|
-
else
|
119
|
-
super("Cannot have a has_many :through association.")
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError # :nodoc:
|
125
|
-
def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
|
126
|
-
if owner_class_name && reflection && source_reflection
|
127
|
-
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
|
128
|
-
else
|
129
|
-
super("Cannot have a has_many :through association.")
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
class HasOneThroughCantAssociateThroughCollection < ActiveRecordError # :nodoc:
|
135
|
-
def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
|
136
|
-
if owner_class_name && reflection && through_reflection
|
137
|
-
super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
|
138
|
-
else
|
139
|
-
super("Cannot have a has_one :through association.")
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
class HasOneAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
|
145
|
-
def initialize(owner_class_name = nil, reflection = nil)
|
146
|
-
if owner_class_name && reflection
|
147
|
-
super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
|
148
|
-
else
|
149
|
-
super("Cannot have a has_one :through association.")
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError # :nodoc:
|
155
|
-
def initialize(reflection = nil)
|
156
|
-
if reflection
|
157
|
-
through_reflection = reflection.through_reflection
|
158
|
-
source_reflection_names = reflection.source_reflection_names
|
159
|
-
source_associations = reflection.through_reflection.klass._reflections.keys
|
160
|
-
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 ')}?")
|
161
|
-
else
|
162
|
-
super("Could not find the source association(s).")
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
class HasManyThroughOrderError < ActiveRecordError # :nodoc:
|
168
|
-
def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
|
169
|
-
if owner_class_name && reflection && through_reflection
|
170
|
-
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through '#{owner_class_name}##{through_reflection.name}' before the through association is defined.")
|
171
|
-
else
|
172
|
-
super("Cannot have a has_many :through association before the through association is defined.")
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError # :nodoc:
|
178
|
-
def initialize(owner = nil, reflection = nil)
|
179
|
-
if owner && reflection
|
180
|
-
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
|
181
|
-
else
|
182
|
-
super("Cannot modify association.")
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
class CompositePrimaryKeyMismatchError < ActiveRecordError # :nodoc:
|
188
|
-
attr_reader :reflection
|
189
|
-
|
190
|
-
def initialize(reflection = nil)
|
191
|
-
if reflection
|
192
|
-
if reflection.has_one? || reflection.collection?
|
193
|
-
super("Association #{reflection.active_record}##{reflection.name} primary key #{reflection.active_record_primary_key} doesn't match with foreign key #{reflection.foreign_key}. Please specify query_constraints, or primary_key and foreign_key values.")
|
194
|
-
else
|
195
|
-
super("Association #{reflection.active_record}##{reflection.name} primary key #{reflection.association_primary_key} doesn't match with foreign key #{reflection.foreign_key}. Please specify query_constraints, or primary_key and foreign_key values.")
|
196
|
-
end
|
197
|
-
else
|
198
|
-
super("Association primary key doesn't match with foreign key.")
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
class AmbiguousSourceReflectionForThroughAssociation < ActiveRecordError # :nodoc:
|
204
|
-
def initialize(klass, macro, association_name, options, possible_sources)
|
205
|
-
example_options = options.dup
|
206
|
-
example_options[:source] = possible_sources.first
|
207
|
-
|
208
|
-
super("Ambiguous source reflection for through association. Please " \
|
209
|
-
"specify a :source directive on your declaration like:\n" \
|
210
|
-
"\n" \
|
211
|
-
" class #{klass} < ActiveRecord::Base\n" \
|
212
|
-
" #{macro} :#{association_name}, #{example_options}\n" \
|
213
|
-
" end"
|
214
|
-
)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
|
219
|
-
end
|
220
|
-
|
221
|
-
class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
|
222
|
-
end
|
223
|
-
|
224
|
-
class ThroughNestedAssociationsAreReadonly < ActiveRecordError # :nodoc:
|
225
|
-
def initialize(owner = nil, reflection = nil)
|
226
|
-
if owner && reflection
|
227
|
-
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
|
228
|
-
else
|
229
|
-
super("Through nested associations are read-only.")
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
|
235
|
-
end
|
236
|
-
|
237
|
-
class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
|
238
|
-
end
|
239
|
-
|
240
|
-
# This error is raised when trying to eager load a polymorphic association using a JOIN.
|
241
|
-
# Eager loading polymorphic associations is only possible with
|
242
|
-
# {ActiveRecord::Relation#preload}[rdoc-ref:QueryMethods#preload].
|
243
|
-
class EagerLoadPolymorphicError < ActiveRecordError
|
244
|
-
def initialize(reflection = nil)
|
245
|
-
if reflection
|
246
|
-
super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
|
247
|
-
else
|
248
|
-
super("Eager load polymorphic error.")
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
# This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
|
254
|
-
# (has_many, has_one) when there is at least 1 child associated instance.
|
255
|
-
# ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
|
256
|
-
class DeleteRestrictionError < ActiveRecordError # :nodoc:
|
257
|
-
def initialize(name = nil)
|
258
|
-
if name
|
259
|
-
super("Cannot delete record because of dependent #{name}")
|
260
|
-
else
|
261
|
-
super("Delete restriction error.")
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
4
|
# See ActiveRecord::Associations::ClassMethods for documentation.
|
267
5
|
module Associations # :nodoc:
|
268
6
|
extend ActiveSupport::Autoload
|
@@ -31,7 +31,7 @@ module ActiveRecord
|
|
31
31
|
# person.name_in_database # => "Alice"
|
32
32
|
# person.saved_change_to_name? # => true
|
33
33
|
# person.saved_change_to_name # => ["Allison", "Alice"]
|
34
|
-
# person.
|
34
|
+
# person.name_before_last_save # => "Allison"
|
35
35
|
#
|
36
36
|
# Similar to ActiveModel::Dirty, methods can be invoked as
|
37
37
|
# +saved_change_to_name?+ or by passing an argument to the generic method
|
@@ -8,11 +8,11 @@ module ActiveRecord
|
|
8
8
|
|
9
9
|
module ClassMethods # :nodoc:
|
10
10
|
private
|
11
|
-
def define_method_attribute(
|
11
|
+
def define_method_attribute(canonical_name, owner:, as: canonical_name)
|
12
12
|
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
13
|
-
owner,
|
13
|
+
owner, canonical_name
|
14
14
|
) do |temp_method_name, attr_name_expr|
|
15
|
-
owner.define_cached_method(
|
15
|
+
owner.define_cached_method(temp_method_name, as: as, namespace: :active_record) do |batch|
|
16
16
|
batch <<
|
17
17
|
"def #{temp_method_name}" <<
|
18
18
|
" _read_attribute(#{attr_name_expr}) { |n| missing_attribute(n, caller) }" <<
|
@@ -12,11 +12,11 @@ module ActiveRecord
|
|
12
12
|
|
13
13
|
module ClassMethods # :nodoc:
|
14
14
|
private
|
15
|
-
def define_method_attribute=(
|
15
|
+
def define_method_attribute=(canonical_name, owner:, as: canonical_name)
|
16
16
|
ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
|
17
|
-
owner,
|
17
|
+
owner, canonical_name, writer: true,
|
18
18
|
) do |temp_method_name, attr_name_expr|
|
19
|
-
owner.define_cached_method("#{
|
19
|
+
owner.define_cached_method(temp_method_name, as: "#{as}=", namespace: :active_record) do |batch|
|
20
20
|
batch <<
|
21
21
|
"def #{temp_method_name}(value)" <<
|
22
22
|
" _write_attribute(#{attr_name_expr}, value)" <<
|
@@ -77,6 +77,13 @@ module ActiveRecord
|
|
77
77
|
# alias attributes in Active Record are lazily generated
|
78
78
|
end
|
79
79
|
|
80
|
+
def generate_alias_attribute_methods(code_generator, new_name, old_name) # :nodoc:
|
81
|
+
attribute_method_patterns.each do |pattern|
|
82
|
+
alias_attribute_method_definition(code_generator, pattern, new_name, old_name)
|
83
|
+
end
|
84
|
+
attribute_method_patterns_cache.clear
|
85
|
+
end
|
86
|
+
|
80
87
|
def alias_attribute_method_definition(code_generator, pattern, new_name, old_name)
|
81
88
|
old_name = old_name.to_s
|
82
89
|
|
@@ -84,12 +91,7 @@ module ActiveRecord
|
|
84
91
|
raise ArgumentError, "#{self.name} model aliases `#{old_name}`, but `#{old_name}` is not an attribute. " \
|
85
92
|
"Use `alias_method :#{new_name}, :#{old_name}` or define the method manually."
|
86
93
|
else
|
87
|
-
|
88
|
-
parameters = pattern.parameters
|
89
|
-
|
90
|
-
define_proxy_call(code_generator, method_name, pattern.proxy_target, parameters, old_name,
|
91
|
-
namespace: :proxy_alias_attribute
|
92
|
-
)
|
94
|
+
define_attribute_method_pattern(pattern, old_name, owner: code_generator, as: new_name, override: true)
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|