In my Rails project, I have a model object which has an existing column called 'permanent' of type 'Boolean'. I need to change this column to an Integer with possible values of 1, 2, 3. Is there any way for me to update the existing data in the DB (through the rails migration) such that all rows with 'permanent' as false are changed to 1 and all rows with 'permanent' as true are changed to 2.
1 Answer
I am using Postgres. Not sure whether this solution works for other databases. people table used as an example - do not forget to change the table name to your own.
def up
change_column :people, :permanent, 'integer USING CAST(permanent AS integer)'
Person.connection.execute("UPDATE people SET permanent = CASE permanent WHEN 0 THEN 1 WHEN 1 THEN 2 END")
end
def down
Person.connection.execute("UPDATE people SET permanent = CASE permanent WHEN 1 THEN 0 WHEN 2 THEN 1 END")
change_column :people, :permanent, 'boolean USING CAST(permanent AS boolean)'
end
5 Comments
ray
Above can be done by rake task. It is always better to use SQL queries to do such operations.
Eldar
@ray thanks for your advice! Why is it better to use SQL queries for such operations?
ray
Actual motive to write migration is to use
ActiveRecord::Migration methods, here execute method will be better one to run SQL to update existing data. Otherwise I could run migration in controller also like ActiveRecord::Migration.create_table.. if conditionray
Perhaps your answer do not harm and will work properly as if you have provided proper
down method & handled well. But it do not satisfy coding convention.Eldar
@ray - I updated the solution according to your comments, does it satisfy to coding conventions now?