Class: ActiveRecord::Associations::Builder::BelongsTo
Do not use. This class is for internal use only.
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
SingularAssociation,
Association
|
|
|
Instance Chain:
self,
SingularAssociation,
Association
|
|
| Inherits: |
ActiveRecord::Associations::Builder::SingularAssociation
|
| Defined in: | activerecord/lib/active_record/associations/builder/belongs_to.rb |
Constant Summary
Association - Inherited
Class Attribute Summary
Association - Inherited
Class Method Summary
- .touch_record(o, change_method, name, touch)
- .add_counter_cache_callbacks(model, reflection) private
- .add_default_callbacks(model, reflection) private
- .add_destroy_callbacks(model, reflection) private
- .add_touch_callbacks(model, reflection) private
- .define_callbacks(model, reflection) private
- .define_change_tracking_methods(model, reflection, mixin) private
- .define_validations(model, reflection) private
- .macro private
- .valid_dependent_options private
- .valid_options(options) private
SingularAssociation - Inherited
| .define_callbacks, .define_accessors, | |
| .define_constructors | Defines the (build|create)_association methods for belongs_to or has_one association. |
| .valid_options | |
Association - Inherited
| .build, .create_reflection, .add_after_commit_jobs_callback, .add_destroy_callbacks, .build_scope, .check_dependent_options, | |
| .define_accessors | Defines the setter and getter methods for the association class Post < |
| .define_callbacks, .define_change_tracking_methods, .define_extensions, .define_validations, .macro, .valid_dependent_options, .valid_options, .validate_options | |
Class Method Details
.add_counter_cache_callbacks(model, reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 28
def self.add_counter_cache_callbacks(model, reflection) cache_column = reflection.counter_cache_column name = reflection.name model.after_update lambda { |record| association = association(name) if association.saved_change_to_target? association.increment_counters association.decrement_counters_before_last_save end } klass = reflection.class_name.safe_constantize klass._counter_cache_columns = (klass._counter_cache_columns | [cache_column]).freeze if klass && klass.respond_to?(:_counter_cache_columns) model.counter_cached_association_names = (model.counter_cached_association_names | [reflection.name]).freeze end
.add_default_callbacks(model, reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 115
def self.add_default_callbacks(model, reflection) name = reflection.name default = reflection.[:default] model.before_validation lambda { |o| o.association(name).default(&default) } end
.add_destroy_callbacks(model, reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 123
def self.add_destroy_callbacks(model, reflection) if reflection.deprecated? # If :dependent is set, destroying the record has some side effect that # would no longer happen if the association is removed. model.before_destroy do report_deprecated_association(reflection, context: ":dependent has a side effect here") end end model.after_destroy lambda { |o| o.association(reflection.name).handle_dependency } end
.add_touch_callbacks(model, reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 92
def self.add_touch_callbacks(model, reflection) name = reflection.name touch = reflection.[:touch] callback = lambda { |change_method| lambda { |record| BelongsTo.touch_record(record, change_method, name, touch) }} if reflection.counter_cache_column touch_callback = callback.(:saved_change_to_attribute) update_callback = lambda { |record| instance_exec(record, &touch_callback) unless association(reflection.name).saved_change_to_target? } model.after_update update_callback, if: :saved_changes? else model.after_create callback.(:saved_change_to_attribute), if: :saved_changes? model.after_update callback.(:saved_change_to_attribute), if: :saved_changes? model.after_destroy callback.(:attribute_change_to_be_saved) end model.after_touch callback.(:attribute_change_to_be_saved) end
.define_callbacks(model, reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 21
def self.define_callbacks(model, reflection) super add_counter_cache_callbacks(model, reflection) if reflection.[:counter_cache] add_touch_callbacks(model, reflection) if reflection.[:touch] add_default_callbacks(model, reflection) if reflection.[:default] end
.define_change_tracking_methods(model, reflection, mixin) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 170
def self.define_change_tracking_methods(model, reflection, mixin) name = reflection.name mixin.define_cached_method(:"#{name}_changed?", namespace: :association_changed) do |batch| batch << <<~RUBY def #{name}_changed? association = association(:#{name}) deprecated_associations_api_guard(association, :#{name}_changed?) association.target_changed? end RUBY end mixin.define_cached_method(:"#{name}_previously_changed?", namespace: :association_previously_changed) do |batch| batch << <<~RUBY def #{name}_previously_changed? association = association(:#{name}) deprecated_associations_api_guard(association, :#{name}_previously_changed?) association.target_previously_changed? end RUBY end end
.define_validations(model, reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 135
def self.define_validations(model, reflection) if reflection..key?(:required) reflection.[:optional] = !reflection..delete(:required) end if reflection.[:optional].nil? required = model.belongs_to_required_by_default else required = !reflection.[:optional] end super if required if ActiveRecord.belongs_to_required_validates_foreign_key model.validates_presence_of reflection.name, message: :required else name = reflection.name polymorphic = reflection.polymorphic? condition = lambda { |record| association = record.association(name) fk_missing_or_changed = association.foreign_key.any? do |fk| record._read_attribute(fk).nil? || record.attribute_changed?(fk) end fk_missing_or_changed || (polymorphic && (record._read_attribute(association.foreign_type).nil? || record.attribute_changed?(association.foreign_type))) } model.validates_presence_of reflection.name, message: :required, if: condition end end end
.macro (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 5
def self.macro :belongs_to end
.touch_record(o, change_method, name, touch)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 46
def self.touch_record(o, change_method, name, touch) # :nodoc: association = o.association(name) foreign_key = association.foreign_key if foreign_key.any? { |key| o.public_send(change_method, key) } read_old = lambda do |column| change = o.public_send(change_method, column) change ? change.first : o._read_attribute(column) end old_reference = foreign_key.map_value { |key| read_old.call(key) } if old_reference reflection = association.reflection if reflection.polymorphic? type = read_old.call(association.foreign_type) || o.public_send(association.foreign_type) klass = o.class.polymorphic_class_for(type) else klass = association.klass end old_route = reflection.association_route(origin_class: o.class, destination_class: klass) old_origin_id = old_route._origin_key.map_value { |key| read_old.call(key) } unless foreign_key.composite? && old_origin_id.any?(nil) old_record = klass.find_by(old_route.destination_key.name => [old_origin_id]) end if old_record if touch != true old_record.touch_later(touch) else old_record.touch_later end end end end record = o.public_send name if record && record.persisted? if touch != true record.touch_later(touch) else record.touch_later end end end
.valid_dependent_options (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 17
def self. [:destroy, :delete, :destroy_async] end
.valid_options(options) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/builder/belongs_to.rb', line 9
def self.() valid = super + [:polymorphic, :counter_cache, :optional, :default] valid << :class_name unless [:polymorphic] valid << :foreign_type if [:polymorphic] valid << :ensuring_owner_was if [:dependent] == :destroy_async valid end