From pictures to picturables

This article tries to explain how to convert existing class in Ruby on Rails to a class that can be used in polymorphic association class. As the beginning, I do recommend to read article about polymorphic associations. It explains what they are and how they work.

The whole process will be described on classes Picture (represents picture) and Item (an item that needs a picture).

1. First of all, it is necessary to create columns for the pictures table. The best way is to use migrations. So, create file e.g. 013_convert_pictures_to_polymorph.rb in your db/migrate directory. It should contain something like:

class ConvertPicturesToPolymorph < ActiveRecord::Migration

  def self.up
    # Change old item_id identifier to new picturable_id
    rename_column :pictures, :item_id, :picturable_id
    # Add type of association
    add_column :pictures, :picturable_type, :string, :length => 50
    # Fill in the type of association
    execute "update pictures set picturable_type = \"Item\""
  end


  def self.down
    # Bring it back
    rename_column :pictures, :picturable_id, :item_id
    remove_column :pictures, :picturable_type
  end
end

now run:

rake migrate 

to create the columns.

2. Once the appropriate columns were created, it is necessary to change the Item class. Change the

  has_many  :pictures

to

  has_many  :pictures, :as => :picturable

3. Now change the Picture class. Change

  belongs_to :item

to

  belongs_to :picturable, :polymorphic => true

Make sure, there is no “item” left in the Picture class. If so, change it to picturable and make sure all picturables have the method you are using.

4. Creating a new class enriched by pictures is simple. Just add

  has_many  :pictures, :as => :picturable

to your class.

5. Last but not least, change your fixtures. The easiest way is to export the current data from your database. For this purpose I do use manage_fixtures plugin.

Good luck!