We had a Rental model that had a column which is an enum type.
class Rental < ApplicationRecord enum delivery_and_return_type: %i[pickup courier post]
We needed to remove the "courier" option on the enum.
We created a migration to remove the "courier" type and change all existing delivery_and_return_type into a "post". The migration implementation is this:
class RentalCourierToRentalPost < ActiveRecord::Migration[5.2] def change Rental.where(delivery_and_return_type: 'courier').each do |rental| rental.update(delivery_and_return_type: 'post') end end end
Everything went well in development. However there was an issue when pushed the code to production and ran the migration.
Since delivery_and_return_type
is implemented as an enum on Rental model, when the migration ran on production, it could no longer find the "courier" option because we already removed it on the Rental model.
class Rental < ApplicationRecord enum delivery_and_return_type: %i[pickup post]
First step is to remove courier
as an option on the Rental model.
class Rental < ApplicationRecord enum delivery_and_return_type: %i[pickup post]
Since delivery_and_return_type
is saved as an integer in the database
create_table "rentals", force: :cascade do |t| t.integer "delivery_and_return_type"
We need to use the integer value on the migration so the code changes on the enum array will not affect the migration.
courier
is represented as 1 and post
is represented as 2. This means that all the rentals that have courier
as return_and_delivery_type
is automatically turned in to post
, which is what we need. However, all the rentals that have "courier" return_and_delivery_type
will have an incorrect value on DB.
The solution is to change the migration to this
class RentalCourierToRentalPost < ActiveRecord::Migration[5.2] def change # `enum delivery_and_return_type: %i[pickup courier post]` # courier is represented as one on the enum array # post is represented as two on the enum array Rental.where(delivery_and_return_type: 2).each do |rental| rental.update(delivery_and_return_type: 1) end end end
Now we have successfully migrated data and created a migration code that is not dependent on the enum array values.