diff options
author | Jon Leighton <j@jonathanleighton.com> | 2011-01-16 19:34:08 +0000 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2011-01-16 13:43:53 -0800 |
commit | ef79b917848f07b61e3243027f5e2ce4bc006d78 (patch) | |
tree | cbb8988b9219d6996e083eb6bb9000fd3be4a374 /activerecord | |
parent | bf24fe810c0591619ac01cc88d8a40423895d9d7 (diff) | |
download | rails-ef79b917848f07b61e3243027f5e2ce4bc006d78.tar.gz rails-ef79b917848f07b61e3243027f5e2ce4bc006d78.tar.bz2 rails-ef79b917848f07b61e3243027f5e2ce4bc006d78.zip |
Abstract common code from BelongsToAssociation and HasOneAssociation into SingularAssociation
Diffstat (limited to 'activerecord')
5 files changed, 43 insertions, 41 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 4760a5fa57..e539e4968b 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -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' diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index 7f6e335858..addc64cb42 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -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 diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 1abea8d831..a818a780ed 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -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 diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index c29ab8dcec..c38843ea68 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -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) diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb new file mode 100644 index 0000000000..023f7caf68 --- /dev/null +++ b/activerecord/lib/active_record/associations/singular_association.rb @@ -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 |