Chaker Benhamed
Home | |
Manipulating schema migrations through rails console
over 4 years ago.
Sometimes when you add a field in Model in your rails application. you run the migration and all go well. However, another day you mess up with your database directly and now your field is missing and your application can't start. If you run rake db:migrate it says that no migration is pending. Either you delete the database and start over again or you simply can force the migration to work using a query to the database.
First let's check our migration status through rake db:migrate:staus :
➜ blog git:(master) rake db:migrate:status database: blog Status Migration ID Migration Name -------------------------------------------------- up 20160727113335 Create friendly id slugs up 20160727113510 Create posts up 20160727223610 Devise create users up 20160729164741 Add view count to posts up 20160806103231 Add draft to posts
where does rails keep this migration??
If you check you're database (I'm using postgress here) you will find a schema_migrations table
blog=# \d schema_migrations Table "public.schema_migrations" Column | Type | Modifiers ---------+-------------------+----------- version | character varying | not null Indexes: "unique_schema_migrations" UNIQUE, btree (version)
if we select all records we will get our migrations versions the same as above with rake db:migrate:status (without any information about the migration)
blog=# select * from schema_migrations; version ---------------- 20160727113335 20160727113510 20160727223610 20160729164741 20160806103231 (5 rows)
So those migration are up because the version number exist in this table. for example if we have a problem with the view_count we can delete the migration version associated with that field like this:
blog=# delete from schema_migrations where version = '20160729164741';
than if we run rake db:migrate:status
➜ blog git:(master) rake db:migrate:status database: blog Status Migration ID Migration Name -------------------------------------------------- up 20160727113335 Create friendly id slugs up 20160727113510 Create posts up 20160727223610 Devise create users down 20160729164741 Add view count to posts up 20160806103231 Add draft to posts
than we can run rake db:migrate.
Of course this is handy sometimes but you can mess up something doing this through the RDBMS. Rather you can use rails console with a model for the migration table (after all it's a model).
2.3.1 :001 > class SchemaMigration < ActiveRecord::Base; self.primary_key = :version; end => :version class SchemaMigration < ActiveRecord::Base; self.primary_key = :version; end 2.3.1 :002 > SchemaMigration.first SchemaMigration Load (2.1ms) SELECT "schema_migrations".* FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC LIMIT 1 => #<SchemaMigration version: "20160727113335">
This way you avoid using SQL directly.