Class: ActiveRecord::Reflection::AbstractReflection
- Inherits:
-
Object
- Object
- ActiveRecord::Reflection::AbstractReflection
show all
- Defined in:
- activerecord/lib/active_record/reflection.rb
Overview
Instance Method Summary
collapse
-
#alias_candidate(name) ⇒ Object
-
#build_association(attributes, &block) ⇒ Object
Returns a new, unsaved instance of the associated class.
-
#build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) ⇒ Object
-
#chain ⇒ Object
-
#check_validity_of_inverse! ⇒ Object
-
#class_name ⇒ Object
Returns the class name for the macro.
-
#constraints ⇒ Object
-
#counter_cache_column ⇒ Object
-
#counter_must_be_updated_by_has_many? ⇒ Boolean
-
#has_cached_counter? ⇒ Boolean
Returns whether a counter cache should be used for this association.
-
#initialize ⇒ AbstractReflection
constructor
A new instance of AbstractReflection.
-
#inverse_of ⇒ Object
-
#inverse_updates_counter_in_memory? ⇒ Boolean
-
#inverse_which_updates_counter_cache ⇒ Object
(also: #inverse_updates_counter_cache?)
We need to avoid the following situation:.
-
#join_scope(table, foreign_table, foreign_klass) ⇒ Object
-
#join_scopes(table, predicate_builder, klass = self.klass, record = nil) ⇒ Object
-
#klass_join_scope(table, predicate_builder) ⇒ Object
-
#scopes ⇒ Object
Returns a list of scopes that should be applied for this Reflection object when querying the database.
-
#strict_loading? ⇒ Boolean
-
#strict_loading_violation_message(owner) ⇒ Object
-
#table_name ⇒ Object
-
#through_reflection? ⇒ Boolean
Constructor Details
Returns a new instance of AbstractReflection.
155
156
157
158
159
160
161
|
# File 'activerecord/lib/active_record/reflection.rb', line 155
def initialize
@class_name = nil
@counter_cache_column = nil
@inverse_of = nil
@inverse_which_updates_counter_cache_defined = false
@inverse_which_updates_counter_cache = nil
end
|
Instance Method Details
#alias_candidate(name) ⇒ Object
303
304
305
|
# File 'activerecord/lib/active_record/reflection.rb', line 303
def alias_candidate(name)
"#{plural_name}_#{name}"
end
|
#build_association(attributes, &block) ⇒ Object
Returns a new, unsaved instance of the associated class. attributes
will be passed to the class’s constructor.
173
174
175
|
# File 'activerecord/lib/active_record/reflection.rb', line 173
def build_association(attributes, &block)
klass.new(attributes, &block)
end
|
#build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) ⇒ Object
311
312
313
314
315
316
317
|
# File 'activerecord/lib/active_record/reflection.rb', line 311
def build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass)
Relation.create(
klass,
table: table,
predicate_builder: predicate_builder
)
end
|
307
308
309
|
# File 'activerecord/lib/active_record/reflection.rb', line 307
def chain
collect_join_chain
end
|
#check_validity_of_inverse! ⇒ Object
#class_name ⇒ Object
Returns the class name for the macro.
composed_of :balance, class_name: 'Money'
returns 'Money'
has_many :clients
returns 'Client'
181
182
183
|
# File 'activerecord/lib/active_record/reflection.rb', line 181
def class_name
@class_name ||= -(options[:class_name] || derive_class_name).to_s
end
|
#constraints ⇒ Object
231
232
233
|
# File 'activerecord/lib/active_record/reflection.rb', line 231
def constraints
chain.flat_map(&:scopes)
end
|
#counter_cache_column ⇒ Object
235
236
237
238
239
240
241
242
243
244
245
|
# File 'activerecord/lib/active_record/reflection.rb', line 235
def counter_cache_column
@counter_cache_column ||= if belongs_to?
if options[:counter_cache] == true
-"#{active_record.name.demodulize.underscore.pluralize}_count"
elsif options[:counter_cache]
-options[:counter_cache].to_s
end
else
-(options[:counter_cache]&.to_s || "#{name}_count")
end
end
|
#counter_must_be_updated_by_has_many? ⇒ Boolean
299
300
301
|
# File 'activerecord/lib/active_record/reflection.rb', line 299
def counter_must_be_updated_by_has_many?
!inverse_updates_counter_in_memory? && has_cached_counter?
end
|
#has_cached_counter? ⇒ Boolean
Returns whether a counter cache should be used for this association.
The counter_cache option must be given on either the owner or inverse association, and the column must be present on the owner.
293
294
295
296
297
|
# File 'activerecord/lib/active_record/reflection.rb', line 293
def has_cached_counter?
options[:counter_cache] ||
inverse_which_updates_counter_cache && inverse_which_updates_counter_cache.options[:counter_cache] &&
active_record.has_attribute?(counter_cache_column)
end
|
#inverse_of ⇒ Object
247
248
249
250
251
|
# File 'activerecord/lib/active_record/reflection.rb', line 247
def inverse_of
return unless inverse_name
@inverse_of ||= klass._reflect_on_association inverse_name
end
|
#inverse_updates_counter_in_memory? ⇒ Boolean
285
286
287
|
# File 'activerecord/lib/active_record/reflection.rb', line 285
def inverse_updates_counter_in_memory?
inverse_of && inverse_which_updates_counter_cache == inverse_of
end
|
#inverse_which_updates_counter_cache ⇒ Object
Also known as:
inverse_updates_counter_cache?
We need to avoid the following situation:
* An associated record is deleted via record.destroy
* Hence the callbacks run, and they find a belongs_to on the record with a
:counter_cache options which points back at our owner. So they update the
counter cache.
* In which case, we must make sure to *not* update the counter cache, or else
it will be decremented twice.
Hence this method.
274
275
276
277
278
279
280
281
282
|
# File 'activerecord/lib/active_record/reflection.rb', line 274
def inverse_which_updates_counter_cache
unless @inverse_which_updates_counter_cache_defined
@inverse_which_updates_counter_cache = klass.reflect_on_all_associations(:belongs_to).find do |inverse|
inverse.counter_cache_column == counter_cache_column
end
@inverse_which_updates_counter_cache_defined = true
end
@inverse_which_updates_counter_cache
end
|
#join_scope(table, foreign_table, foreign_klass) ⇒ Object
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
# File 'activerecord/lib/active_record/reflection.rb', line 191
def join_scope(table, foreign_table, foreign_klass)
predicate_builder = predicate_builder(table)
scope_chain_items = join_scopes(table, predicate_builder)
klass_scope = klass_join_scope(table, predicate_builder)
if type
klass_scope.where!(type => foreign_klass.polymorphic_name)
end
scope_chain_items.inject(klass_scope, &:merge!)
primary_key_column_names = Array(join_primary_key)
foreign_key_column_names = Array(join_foreign_key)
primary_foreign_key_pairs = primary_key_column_names.zip(foreign_key_column_names)
primary_foreign_key_pairs.each do |primary_key_column_name, foreign_key_column_name|
klass_scope.where!(table[primary_key_column_name].eq(foreign_table[foreign_key_column_name]))
end
if klass.finder_needs_type_condition?
klass_scope.where!(klass.send(:type_condition, table))
end
klass_scope
end
|
#join_scopes(table, predicate_builder, klass = self.klass, record = nil) ⇒ Object
218
219
220
221
222
223
224
|
# File 'activerecord/lib/active_record/reflection.rb', line 218
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) if scope
[scope_for(build_scope(table, predicate_builder, klass), record)]
else
[]
end
end
|
#klass_join_scope(table, predicate_builder) ⇒ Object
226
227
228
229
|
# File 'activerecord/lib/active_record/reflection.rb', line 226
def klass_join_scope(table, predicate_builder) relation = build_scope(table, predicate_builder)
klass.scope_for_association(relation)
end
|
Returns a list of scopes that should be applied for this Reflection object when querying the database.
187
188
189
|
# File 'activerecord/lib/active_record/reflection.rb', line 187
def scopes
scope ? [scope] : []
end
|
#strict_loading? ⇒ Boolean
319
320
321
|
# File 'activerecord/lib/active_record/reflection.rb', line 319
def strict_loading?
options[:strict_loading]
end
|
#strict_loading_violation_message(owner) ⇒ Object
323
324
325
326
327
|
# File 'activerecord/lib/active_record/reflection.rb', line 323
def strict_loading_violation_message(owner)
message = +"`#{owner}` is marked for strict_loading."
message << " The #{polymorphic? ? "polymorphic association" : "#{klass} association"}"
message << " named `:#{name}` cannot be lazily loaded."
end
|
#table_name ⇒ Object
167
168
169
|
# File 'activerecord/lib/active_record/reflection.rb', line 167
def table_name
klass.table_name
end
|
#through_reflection? ⇒ Boolean
163
164
165
|
# File 'activerecord/lib/active_record/reflection.rb', line 163
def through_reflection?
false
end
|