From 075c81feec87b1e5bfec27ed585c4ab613c2d174 Mon Sep 17 00:00:00 2001 From: Ulisses Almeida + Kassio Borges Date: Mon, 8 Dec 2014 17:43:16 -0200 Subject: Add foreign_type option for polymorphic has_one and has_many. To be possible to use a custom column name to save/read the polymorphic associated type in a has_many or has_one polymorphic association, now users can use the option :foreign_type to inform in what column the associated object type will be saved. --- activerecord/lib/active_record/associations.rb | 12 ++++++++++++ .../lib/active_record/associations/builder/has_many.rb | 2 +- .../lib/active_record/associations/builder/has_one.rb | 2 +- activerecord/lib/active_record/reflection.rb | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index eb21712f96..cd5fdd5964 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1176,6 +1176,12 @@ module ActiveRecord # Specify the foreign key used for the association. By default this is guessed to be the name # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+ # association will use "person_id" as the default :foreign_key. + # [:foreign_type] + # Specify the column used to store the associated object's type, if this is a polymorphic + # association. By default this is guessed to be the name of the polymorphic association + # specified on "as" option with a "_type" suffix. So a class that defines a + # has_many :tags, as: :taggable association will use "taggable_type" as the + # default :foreign_type. # [:primary_key] # Specify the name of the column to use as the primary key for the association. By default this is +id+. # [:dependent] @@ -1323,6 +1329,12 @@ module ActiveRecord # Specify the foreign key used for the association. By default this is guessed to be the name # of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association # will use "person_id" as the default :foreign_key. + # [:foreign_type] + # Specify the column used to store the associated object's type, if this is a polymorphic + # association. By default this is guessed to be the name of the polymorphic association + # specified on "as" option with a "_type" suffix. So a class that defines a + # has_one :tag, as: :taggable association will use "taggable_type" as the + # default :foreign_type. # [:primary_key] # Specify the method that returns the primary key used for the association. By default this is +id+. # [:as] diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb index 4c8c826f76..1b87f92170 100644 --- a/activerecord/lib/active_record/associations/builder/has_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_many.rb @@ -5,7 +5,7 @@ module ActiveRecord::Associations::Builder end def valid_options - super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache, :join_table] + super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache, :join_table, :foreign_type] end def self.valid_dependent_options diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb index c194c8ae9a..1387717396 100644 --- a/activerecord/lib/active_record/associations/builder/has_one.rb +++ b/activerecord/lib/active_record/associations/builder/has_one.rb @@ -5,7 +5,7 @@ module ActiveRecord::Associations::Builder end def valid_options - valid = super + [:as] + valid = super + [:as, :foreign_type] valid += [:through, :source, :source_type] if options[:through] valid end diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 4202bc5665..9849e03036 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -277,7 +277,7 @@ module ActiveRecord def initialize(name, scope, options, active_record) super @automatic_inverse_of = nil - @type = options[:as] && "#{options[:as]}_type" + @type = options[:as] && (options[:foreign_type] || "#{options[:as]}_type") @foreign_type = options[:foreign_type] || "#{name}_type" @constructable = calculate_constructable(macro, options) @association_scope_cache = {} -- cgit v1.2.3