Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing an existing has_many relation to polymorphic in Rails 3

I've got an existing has_many relation between two models - call them 'cars' and 'passengers' - with a few thousand 'passengers' belonging to a few hundred 'cards' in my production environment. I'm adding another model, call it 'trains', and I want to change the existing has_many relation between cars and passengers to a polymorphic one relating each passenger to either a car or a train.

What should my migration look like? I want to preserve the existing relations in my database when I migrate, so I'd rather do some table-renaming rather than dropping the one column to replace it with another. Further, I want to be able to do it without opening up the server console and manually editing all the records, so I can just migrate the entire database in one fell swoop when I push my changes to production. Any suggestions?

TL;DR: How do I change an existing has_many relation to a polymorphic one with a new model?

like image 919
James M Avatar asked Apr 27 '13 22:04

James M


People also ask

What is polymorphic relation in rails?

Polymorphic relationship in Rails refers to a type of Active Record association. This concept is used to attach a model to another model that can be of a different type by only having to define one association.

What is polymorphic association in Sequelize?

A polymorphic association consists on two (or more) associations happening with the same foreign key. For example, consider the models Image , Video and Comment . The first two represent something that a user might post. We want to allow comments to be placed in both of them.


1 Answers

You will have to write some migrations like

  1. Add two columns to Passenger table. -> rails g migration change_column_in_passenger

  2. In migration file, write following code in up method

Code:

def up
  rename_column :passengers, :car_id, :transport_id
  add_column :passengers, :transport_type, :string
  Passenger.reset_column_information
  Passenger.update_all(:transport_type => "Car")
end

def down
  rename_column :passengers, :transport_id, :car_id
  remove_column :passengers, :transport_type
end



Hence this migration will update all current Car relation in Passenger. Also will allow train model to have a relation with Passenger.

like image 125
Akshay Vishnoi Avatar answered Oct 01 '22 12:10

Akshay Vishnoi