Class: ActiveRecord::Reflection::AbstractReflection

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/reflection.rb

Overview

Instance Method Summary collapse

Instance Method Details

#alias_candidate(name) ⇒ Object



276
277
278
# File 'lib/active_record/reflection.rb', line 276

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.



156
157
158
# File 'lib/active_record/reflection.rb', line 156

def build_association(attributes, &block)
  klass.new(attributes, &block)
end

#build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) ⇒ Object



284
285
286
287
288
289
290
# File 'lib/active_record/reflection.rb', line 284

def build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass)
  Relation.create(
    klass,
    table: table,
    predicate_builder: predicate_builder
  )
end

#chainObject



280
281
282
# File 'lib/active_record/reflection.rb', line 280

def chain
  collect_join_chain
end

#check_validity_of_inverse!Object



232
233
234
235
236
237
238
# File 'lib/active_record/reflection.rb', line 232

def check_validity_of_inverse!
  unless polymorphic?
    if has_inverse? && inverse_of.nil?
      raise InverseOfAssociationNotFoundError.new(self)
    end
  end
end

#class_nameObject

Returns the class name for the macro.

composed_of :balance, class_name: 'Money' returns 'Money' has_many :clients returns 'Client'



164
165
166
# File 'lib/active_record/reflection.rb', line 164

def class_name
  @class_name ||= -(options[:class_name] || derive_class_name).to_s
end

#constraintsObject



210
211
212
# File 'lib/active_record/reflection.rb', line 210

def constraints
  chain.flat_map(&:scopes)
end

#counter_cache_columnObject



214
215
216
217
218
219
220
221
222
223
224
# File 'lib/active_record/reflection.rb', line 214

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

Returns:

  • (Boolean)


272
273
274
# File 'lib/active_record/reflection.rb', line 272

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.

Returns:

  • (Boolean)


266
267
268
269
270
# File 'lib/active_record/reflection.rb', line 266

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_ofObject



226
227
228
229
230
# File 'lib/active_record/reflection.rb', line 226

def inverse_of
  return unless inverse_name

  @inverse_of ||= klass._reflect_on_association inverse_name
end

#inverse_updates_counter_in_memory?Boolean

Returns:

  • (Boolean)


258
259
260
# File 'lib/active_record/reflection.rb', line 258

def inverse_updates_counter_in_memory?
  inverse_of && inverse_which_updates_counter_cache == inverse_of
end

#inverse_which_updates_counter_cacheObject Also known as: inverse_updates_counter_cache?

This shit is nasty. 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.



250
251
252
253
254
255
# File 'lib/active_record/reflection.rb', line 250

def inverse_which_updates_counter_cache
  return @inverse_which_updates_counter_cache if defined?(@inverse_which_updates_counter_cache)
  @inverse_which_updates_counter_cache = klass.reflect_on_all_associations(:belongs_to).find do |inverse|
    inverse.counter_cache_column == counter_cache_column
  end
end

#join_scope(table, foreign_table, foreign_klass) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/active_record/reflection.rb', line 174

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 = join_primary_key
  foreign_key = join_foreign_key

  klass_scope.where!(table[primary_key].eq(foreign_table[foreign_key]))

  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) ⇒ Object

:nodoc:



197
198
199
200
201
202
203
# File 'lib/active_record/reflection.rb', line 197

def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
  if scope
    [scope_for(build_scope(table, predicate_builder, klass))]
  else
    []
  end
end

#klass_join_scope(table, predicate_builder) ⇒ Object

:nodoc:



205
206
207
208
# File 'lib/active_record/reflection.rb', line 205

def klass_join_scope(table, predicate_builder) # :nodoc:
  relation = build_scope(table, predicate_builder)
  klass.scope_for_association(relation)
end

#scopesObject

Returns a list of scopes that should be applied for this Reflection object when querying the database.



170
171
172
# File 'lib/active_record/reflection.rb', line 170

def scopes
  scope ? [scope] : []
end

#strict_loading?Boolean

Returns:

  • (Boolean)


292
293
294
# File 'lib/active_record/reflection.rb', line 292

def strict_loading?
  options[:strict_loading]
end

#table_nameObject



150
151
152
# File 'lib/active_record/reflection.rb', line 150

def table_name
  klass.table_name
end

#through_reflection?Boolean

:nodoc:

Returns:

  • (Boolean)


146
147
148
# File 'lib/active_record/reflection.rb', line 146

def through_reflection?
  false
end