views:

113

answers:

1

Having this mix of polymorphism and inhertiance, I encounter some weird behaviour:

Migration

class CreateCommons < ActiveRecord::Migration
  def self.up
    create_table :commons do |t|
      t.string :name
      t.string :configurable_type
      t.integer :configurable_id
    end

    create_table :specifics do |t|
      t.integer :number
    end

  end

  def self.down
    drop_table :specifics
    drop_table :commons
  end
end

Models

class Specific < Common
  set_table_name "specifics"
  validates_presence_of :number
  has_one :common, :as => :configurable
end


class Common < ActiveRecord::Base
  belongs_to :configurable, :polymorphic => true
  accepts_nested_attributes_for :configurable

  def attributes=(attributes = {})
    self.configurable_type = attributes[:configurable_type]
    super
  end

  def build_configurable(attributes = {})
     puts "Configurable type before assignment -> #{self.configurable_type}"
    self.configurable = self.configurable_type.classify.constantize.new(attributes)
    puts "Configurable type after assignment -> #{self.configurable_type}"
  end
end

Now - creating new Common, with a Specific as polymorph model, changes :configurable_type column content from Specific to Common - can anybody explain why does it happen and how to fix it? I am clearly stating, that I want to create "Specific" model (and it is created properly), however somehow automagically the column describing type of associated model gains incorrect value... Example below

@common = Common.new({:name => "blah", :configurable_type => "Specific", :configurable_attributes => {:number => 1}})
Configurable type before assignment -> Specific
Configurable type after assignment -> Common
=> #<Common id: nil, name: "blah", configurable_type: "Common", configurable_id: nil>

I suspect it may be related to the fact that Specific inherits from Common...

A: 

Very helpful for me.

But is possible to overload method "build_configurable(attributes = {})" for has_many association ? Object from there arent build with method build_object_name, but object_name.build.

Thanks

Schovi