Hello all,

I'm working with a legacy schema that uses polymorphism and having some 
trouble getting AR to cooperate with it's original design. Looking through 
issues, I've seen a few other requests for enum based polymorphic type 
columns. Personally, I'm not a huge fan of inserting model names into the 
database: it just seems like an enum or table name would be more 
appropriate.

Is there a built-in way to use different values for the polymorphic type 
column? It seems like I can override `ActiveRecord::Base.compute_type`, but 
that's kind of ugly.

I wrote up a monkey patch (using AR 4.0.13 and pretty much untested):

module ActiveRecord
  module Associations
    module BelongsToPolymorphicEnum
      extend ActiveSupport::Concern

      included do
        alias_method_chain :klass, :enum
        alias_method_chain :replace_keys, :enum
      end

      def klass_with_enum
        if klass_types.nil?
          klass_without_enum
        else
          type = klass_types.invert[owner[reflection.foreign_type]]
          type.presence && type.constantize
        end
      end

      private

      def replace_keys_with_enum(record)
        if klass_types.nil?
          replace_keys_without_enum
        else
          super
          owner[reflection.foreign_type] = klass_types[record.class.name]
        end
      end

      def klass_types
        options[:types]
      end
    end

    module BuilderWithPolymorphicEnum
      def valid_options
        super + [:types]
      end
    end

    Builder::BelongsTo.send :include, BuilderWithPolymorphicEnum
    BelongsToPolymorphicAssociation.send :include, BelongsToPolymorphicEnum
  end
end

It allows you to do this:

class Picture < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true, types: { 'Employee' => 1, 
'Product' => 2 }
end

I'm all for conventions, but Polymorphic tables seems like an area in need 
of more configuration options. 

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-core@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to