mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Abstract common code from BelongsToAssociation and HasOneAssociation into SingularAssociation
This commit is contained in:
committed by
Aaron Patterson
parent
bf24fe810c
commit
ef79b91784
@@ -119,6 +119,7 @@ module ActiveRecord
|
||||
# These classes will be loaded when associations are created.
|
||||
# So there is no need to eager load them.
|
||||
autoload :AssociationCollection, 'active_record/associations/association_collection'
|
||||
autoload :SingularAssociation, 'active_record/associations/singular_association'
|
||||
autoload :AssociationProxy, 'active_record/associations/association_proxy'
|
||||
autoload :ThroughAssociation, 'active_record/associations/through_association'
|
||||
autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association'
|
||||
|
||||
@@ -7,14 +7,15 @@ module ActiveRecord
|
||||
# This is the root class of all association proxies ('+ Foo' signifies an included module Foo):
|
||||
#
|
||||
# AssociationProxy
|
||||
# BelongsToAssociation
|
||||
# BelongsToPolymorphicAssociation
|
||||
# SingularAssociaton
|
||||
# HasOneAssociation
|
||||
# HasOneThroughAssociation + ThroughAssociation
|
||||
# BelongsToAssociation
|
||||
# BelongsToPolymorphicAssociation
|
||||
# AssociationCollection
|
||||
# HasAndBelongsToManyAssociation
|
||||
# HasManyAssociation
|
||||
# HasManyThroughAssociation + ThroughAssociation
|
||||
# HasOneAssociation
|
||||
# HasOneThroughAssociation + ThroughAssociation
|
||||
#
|
||||
# Association proxies in Active Record are middlemen between the object that
|
||||
# holds the association, known as the <tt>@owner</tt>, and the actual associated
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
module ActiveRecord
|
||||
# = Active Record Belongs To Associations
|
||||
module Associations
|
||||
class BelongsToAssociation < AssociationProxy #:nodoc:
|
||||
def create(attributes = {})
|
||||
new_record(:create_association, attributes)
|
||||
end
|
||||
|
||||
def create!(attributes = {})
|
||||
build(attributes).tap { |record| record.save! }
|
||||
end
|
||||
|
||||
def build(attributes = {})
|
||||
new_record(:build_association, attributes)
|
||||
end
|
||||
|
||||
class BelongsToAssociation < SingularAssociation #:nodoc:
|
||||
def replace(record)
|
||||
record = record.target if AssociationProxy === record
|
||||
raise_on_type_mismatch(record) if record
|
||||
@@ -34,12 +22,6 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
private
|
||||
def new_record(method, attributes)
|
||||
record = scoped.scoping { @reflection.send(method, attributes) }
|
||||
replace(record)
|
||||
record
|
||||
end
|
||||
|
||||
def update_counters(record)
|
||||
counter_cache_name = @reflection.counter_cache_column
|
||||
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
module ActiveRecord
|
||||
# = Active Record Belongs To Has One Association
|
||||
module Associations
|
||||
class HasOneAssociation < AssociationProxy #:nodoc:
|
||||
def create(attributes = {})
|
||||
new_record(:create_association, attributes)
|
||||
end
|
||||
|
||||
def create!(attributes = {})
|
||||
build(attributes).tap { |record| record.save! }
|
||||
end
|
||||
|
||||
def build(attributes = {})
|
||||
new_record(:build_association, attributes)
|
||||
end
|
||||
|
||||
class HasOneAssociation < SingularAssociation #:nodoc:
|
||||
def replace(record, save = true)
|
||||
record = record.target if AssociationProxy === record
|
||||
raise_on_type_mismatch(record) unless record.nil?
|
||||
@@ -52,12 +40,11 @@ module ActiveRecord
|
||||
alias creation_attributes construct_owner_attributes
|
||||
|
||||
# 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, and
|
||||
# so they are set straight away and do not need to be updated within replace.
|
||||
def new_record(method, attributes)
|
||||
record = scoped.scoping { @reflection.send(method, attributes) }
|
||||
# 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.
|
||||
def set_new_record(record)
|
||||
replace(record, false)
|
||||
record
|
||||
end
|
||||
|
||||
def remove_target!(method)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
module ActiveRecord
|
||||
module Associations
|
||||
class SingularAssociation < AssociationProxy #:nodoc:
|
||||
def create(attributes = {})
|
||||
record = scoped.scoping { @reflection.create_association(attributes) }
|
||||
set_new_record(record)
|
||||
record
|
||||
end
|
||||
|
||||
def create!(attributes = {})
|
||||
build(attributes).tap { |record| record.save! }
|
||||
end
|
||||
|
||||
def build(attributes = {})
|
||||
record = scoped.scoping { @reflection.build_association(attributes) }
|
||||
set_new_record(record)
|
||||
record
|
||||
end
|
||||
|
||||
private
|
||||
# Implemented by subclasses
|
||||
def replace(record)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def set_new_record(record)
|
||||
replace(record)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user