J. Ed
J. Ed

Reputation: 6742

rails: change a relationship to be polymorphic

Let's take a slightly more complex case of the example of polymorphic relationships as seen in the docs (2.9)
Suppose that initially, only a Product can have an Image; We would have something like this-

class Picture < ActiveRecord::Base
  belongs_to :product
end

class Employee < ActiveRecord::Base
  # nothing yet
end

class Product < ActiveRecord::Base
  has_many :pictures
end

After a while, we want to add the ability for an Employee to have an image also;
What kind of migrations do I need to run to make sure that the existing Products' images are preserved and the relationship is now polymorphic, like so-

class Picture < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end

class Employee < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

class Product < ActiveRecord::Base
  has_many :pictures, as: :imageable
end

Upvotes: 4

Views: 1184

Answers (2)

pa3k
pa3k

Reputation: 861

I would write migration like this:

remove_foreign_key  :pictures, :products
add_column :pictures, :imageable_type, :string
rename_column :pictures, :product_id, :imageable_id


Picture.update_all(imageable_type: "Product")

Upvotes: 1

Pardeep Dhingra
Pardeep Dhingra

Reputation: 3946

class AddImageableIdAndTypeToPictures < ActiveRecord::Migration
  def up
    add_column :pictures, :imageable_type, :string
    add_column :pictures, :imageable_id, :integer

    Picture.all.each do |picture| 
      picture.imageable_type = 'Product'
      picture.imageable_id = picture.product_id
      picture.save
    end
  end
end

Upvotes: 2

Related Questions