Class: ActiveRecord::Associations::HasOneAssociation
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
SingularAssociation ,
Association
|
|
Instance Chain:
|
|
Inherits: |
ActiveRecord::Associations::SingularAssociation
|
Defined in: | activerecord/lib/active_record/associations/has_one_association.rb |
Overview
Active Record Has One Association
Class Method Summary
Association
- Inherited
Instance Attribute Summary
ForeignAssociation
- Included
Association
- Inherited
#collection? | Whether the association represent a single record or a collection of records. |
#disable_joins, | |
#loaded? | Has the target been already loaded? |
#options, #owner, #reflection, | |
#stale_target? | The target is stale if the target no longer points to the record(s) that the relevant foreign_key(s) refers to. |
#target, | |
#target= | Sets the target of this association to |
#find_target?, | |
#foreign_key_present? | Returns true if there is a foreign key present on the owner which references the target. |
#violates_strict_loading? |
Instance Method Summary
- #delete(method = options[:dependent])
- #handle_dependency
- #_create_record(attributes, raise_error = false, &block) private
- #nullify_owner_attributes(record) private
- #remove_target!(method) private
- #replace(record, save = true) private
-
#set_new_record(record)
private
The reason that the save param for replace is false, if for create (not just build), is because the setting of the foreign keys is actually handled by the scoping when the record is instantiated, and so they are set straight away and do not need to be updated within replace.
- #transaction_if(value, &block) private
ForeignAssociation
- Included
#nullified_owner_attributes, | |
#set_owner_attributes | Sets the owner attributes on the given record. |
SingularAssociation
- Inherited
#build, | |
#force_reload_reader | Implements the reload reader method, e.g. |
#reader | Implements the reader method, e.g. |
#reset | Resets the loaded flag to |
#writer | Implements the writer method, e.g. |
#_create_record, #find_target, #replace, #scope_for_create, #set_new_record |
Association
- Inherited
#async_load_target, #create, #create!, #extensions, #initialize_attributes, #inversed_from, #inversed_from_queries, | |
#klass | Returns the class of the target. |
#load_target | Loads the target if needed and returns it. |
#loaded! | Asserts the target has been loaded setting the loaded flag to |
#marshal_dump | We can’t dump @reflection and @through_reflection since it contains the scope proc. |
#marshal_load, | |
#reload | Reloads the target and returns |
#remove_inverse_instance | Remove the inverse association, if possible. |
#reset | Resets the loaded flag to |
#reset_negative_cache, #reset_scope, #scope, | |
#set_inverse_instance | Set the inverse association, if possible. |
#set_inverse_instance_from_queries, #set_strict_loading, | |
#association_scope | The scope for this association. |
#build_record, #enqueue_destroy_association, | |
#ensure_klass_exists! | Reader and writer methods call this so that consistent errors are presented when the association target class does not exist. |
#find_target, | |
#foreign_key_for? | Returns true if record contains the foreign_key. |
#inversable?, #inverse_association_for, | |
#inverse_reflection_for | Can be redefined by subclasses, notably polymorphic belongs_to The record parameter is necessary to support polymorphic inverses as we must check for the association in the specific class of the record. |
#invertible_for? | Returns true if inverse association on the given record needs to be set. |
#matches_foreign_key?, | |
#raise_on_type_mismatch! | Raises |
#scope_for_create, | |
#skip_statement_cache? | Returns true if statement cache should be skipped on the association reader. |
#skip_strict_loading, | |
#stale_state | This should be implemented to return the values of the relevant key(s) on the owner, so that when stale_state is different from the value stored on the last find_target, the target is stale. |
#target_scope | Can be overridden (i.e. in |
Constructor Details
This class inherits a constructor from ActiveRecord::Associations::Association
Instance Method Details
#_create_record(attributes, raise_error = false, &block) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/has_one_association.rb', line 133
def _create_record(attributes, raise_error = false, &block) unless owner.persisted? raise ActiveRecord::RecordNotSaved.new("You cannot call create unless the parent is saved", owner) end super end
#delete(method = options[:dependent])
[ GitHub ]# File 'activerecord/lib/active_record/associations/has_one_association.rb', line 26
def delete(method = [:dependent]) if load_target case method when :delete target.delete when :destroy target.destroyed_by_association = reflection target.destroy throw(:abort) unless target.destroyed? when :destroy_async if target.class.query_constraints_list primary_key_column = target.class.query_constraints_list id = primary_key_column.map { |col| target.public_send(col) } else primary_key_column = target.class.primary_key id = target.public_send(primary_key_column) end enqueue_destroy_association( owner_model_name: owner.class.to_s, owner_id: owner.id, association_class: reflection.klass.to_s, association_ids: [id], association_primary_key_column: primary_key_column, ensuring_owner_was_method: .fetch(:ensuring_owner_was, nil) ) when :nullify target.update_columns(nullified_owner_attributes) if target.persisted? end end end
#handle_dependency
[ GitHub ]# File 'activerecord/lib/active_record/associations/has_one_association.rb', line 9
def handle_dependency case [:dependent] when :restrict_with_exception raise ActiveRecord::DeleteRestrictionError.new(reflection.name) if load_target when :restrict_with_error if load_target record = owner.class.human_attribute_name(reflection.name).downcase owner.errors.add(:base, :'restrict_dependent_destroy.has_one', record: record) throw(:abort) end else delete end end
#nullify_owner_attributes(record) (private)
[ GitHub ]#remove_target!(method) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/has_one_association.rb', line 95
def remove_target!(method) case method when :delete target.delete when :destroy target.destroyed_by_association = reflection if target.persisted? target.destroy end else nullify_owner_attributes(target) remove_inverse_instance(target) if target.persisted? && owner.persisted? && !target.save set_owner_attributes(target) raise RecordNotSaved.new( "Failed to remove the existing associated #{reflection.name}. " \ "The record failed to save after its foreign key was set to nil.", target ) end end end
#replace(record, save = true) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/has_one_association.rb', line 59
def replace(record, save = true) raise_on_type_mismatch!(record) if record return target unless load_target || record assigning_another_record = target != record if assigning_another_record || record.has_changes_to_save? save &&= owner.persisted? transaction_if(save) do remove_target!( [:dependent]) if target && !target.destroyed? && assigning_another_record if record set_owner_attributes(record) set_inverse_instance(record) if save && !record.save nullify_owner_attributes(record) set_owner_attributes(target) if target raise RecordNotSaved.new("Failed to save the new associated #{reflection.name}.", record) end end end end self.target = record end
#set_new_record(record) (private)
The reason that the save param for replace is false, if for create (not just build), is because the setting of the foreign keys is actually handled by the scoping when the record is instantiated, and so they are set straight away and do not need to be updated within replace.
# File 'activerecord/lib/active_record/associations/has_one_association.rb', line 91
def set_new_record(record) replace(record, false) end
#transaction_if(value, &block) (private)
[ GitHub ]# File 'activerecord/lib/active_record/associations/has_one_association.rb', line 125
def transaction_if(value, &block) if value reflection.klass.transaction(&block) else yield end end