After migration my PageViewStats
table contains 2 new empty columns:
ad_templatable_id
and ad_templatable_type
. So if I try to query an existing record like so: AdTemplate.find(42).page_view_stats
it returns nothing, but before migration it returns array of PageViewStats
records.
I guess I need to create a rake
task that will populate these 2 new columns with:
1) ad_templatable_id
will contain values from existing ad_template_id
column
2) ad_templatable_type
will contain a string AdTemplate
My guess is correct? :) Is this what I need to do?
Before migration:
# == Schema Information
# # ad_template_id :integer not null
class PageViewStat < ActiveRecord::Base
belongs_to :ad_template
end
class AdTemplate < ActiveRecord::Base
has_many :page_view_stats
end
Applying polymorpic migration:
class AddPolymorphismToPageViewStat < ActiveRecord::Migration
def change
add_reference :page_view_stats, :ad_templatable, polymorphic: true
add_index :page_view_stats, [:ad_templatable_type, :ad_templatable_id],
name: 'index_page_view_stats_on_ad_templatable_type_and_id'
end
end
After migration:
# == Schema Information
# # ad_template_id :integer not null
class PageViewStat < ActiveRecord::Base
belongs_to :ad_templatable, polymorphic: true
end
class AdTemplate < ActiveRecord::Base
has_many :page_view_stats, as: :ad_templatable
end
Yes, creating a rake task is better than performing data migration manually as you can write tests for it.
Another way is to include code to change the data in the migration which is great to ensure that data is migrated when the schema changes, reducing potential downtime e.g.
def up
[code to add new columns]
migrate_data
[code to remove legacy columns]
end
def down
[code to add legacy columns]
rollback_data
[code to remove new columns]
end
private
def migrate_data
[code to make data changes]
end
def rollback_data
[code to reverse data changes]
end
Note, if you do it this way, there are some gotchas, you will need to specify up and down migration seperatly and you should go through the effort of writing code to rollback as well as test.