Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails old migrations fail due to validation in model for new column

I have an application using active admin with devise in production. I try to add user_role to the table admin_users. I also want to validate if the role name is chosen when creating a new admin user. so I add validates :role_id, :presence => true in rails model.

When I run my new migrations on the old database, everything works fine. But when I try to apply the migrations from scratch, the old migration for creating admin user fails because of the validation added in a model, saying undefined method error.

Without changing the old migrations and by having the validation when creating admin users from UI, Is it possible to overcome this situation

like image 732
Priya Avatar asked Apr 22 '18 07:04

Priya


People also ask

How do I reset migration in rails?

just use rake db:reset , that will drop your database (same as undoing all migrations) and reset to the last schema. UPDATE: a more correct approach will be using rake db:migrate:reset . That will drop the database, create it again and run all the migrations, instead of resetting to the latest schema.

How does rails keep track of migrations?

Every time a migration is generated using the rails g migration command, Rails generates the migration file with a unique timestamp. The timestamp is in the format YYYYMMDDHHMMSS . Whenever a migration is run, Rails inserts the migration timestamp into an internal table schema_migrations .

Are rails migrations run in a transaction?

On databases that support transactions with statements that change the schema, migrations are wrapped in a transaction. If the database does not support this then when a migration fails the parts of it that succeeded will not be rolled back. You will have to rollback the changes that were made by hand.


1 Answers

I have faced this issue and the best solution to me seems to be to modify the model inside the migration and remove the problematic validation (for the duration of the migration) by opening the model's class.

Let's say you have a model Employee and a validation on a column firstname is interfering with a particular migration. Assuming you're using Rails 4.2, this should work:

class CreateStoreFromPreferences < ActiveRecord::Migration
  def change
    Employee.class_eval do
      _validators.delete(:firstname)

      _validate_callbacks.each do |callback|
        if callback.raw_filter.respond_to? :attributes
          callback.raw_filter.attributes.delete :firstname
        end
      end
    end

    # actual migration code goes here
  end
end
like image 181
Arpit Chauhan Avatar answered Sep 28 '22 02:09

Arpit Chauhan