Rails 4 how to ignore pending migrations
Rails stores migration information in a table called schema_migrations
.
You can add the version from your migration into that table to skip a specific migration.
The version is the number string which comes before the description in the file name.
[version]_Create_Awesome.rb
Rails: How to delete a pending migration
Sometimes, even dropping a local development database is not a good idea.
There are better ways to delete/destroy a specific migration in your Rails application.
You could use rails d migration
command to destroy a particular migration:
rails d migration MigrationName
To undo the changes corresponding to a particular migration, you can use db:migrate:down
method like this:
rake db:migrate:down VERSION=XXX
Sometimes, things could get more messy and in those situation another handy thing is to take a look at the schema_migrations
table in your database which has all the migrations with their version
saved in it.
You can delete a particular migration from this table like this:
delete from schema_migrations WHERE version = VERSION;
if you don't want that migration to be present anymore.
How temporarily disable needs_migration? check when testing migration?
Testing Rails migration is a bit of a pain so I would rather step back and think about if this needs to be in a Rails migration / tested in a Rails migration.
There are basically two different types of migrations
Schema migrations
Use mostly Rails built in functions. Unless you do some handcrafted SQL I wouldn't bother testing this and trust the framework here.
Data migrations
Data migrations are used to backfill or change data. As data is one of your most valuable assets and loosing or corrupting it is very painful I would definitely recommend to write tests for data migrations.
As mentioned, testing migrations is a bit of a pain so I would try to abstract the data migration code in it's own (service) class. Something like
class DataMigration::UpdateUsername
def self.run
new.run
end
def run
User.all do |batch|
user.update(name: user.name.capitalize)
end
end
end
You can now test the data migration like a normal class like this:
it 'does capitalize the name' do
user = create(:user, name: 'name')
DataMigration::UpdateUsername.run
expect(user.reload.name).to eq('NAME')
end
Now we can use this class in our Rails migration or e.g. just use it in a Rake task. Using it in a Rake task also has the advantages that we can pass in parameters, run several data migrations in parallel (e.g. you have a large data set) or even in a background job which you can't in a Rails migration.
Example
class DataMigration::UpdateUsername
def initialize(start_id:, finish_id:)
@start_id = start_id
@finish_id = finish_id
end
def run
User.find_in_batches(start: start_id, finish: finish_id) do |batch|
batch.each do |user|
user.update(name: user.name.capitalize)
end
end
end
end
Now we can create a custom task for this
namespace :db do
desc "Runs user data migration"
task :update_user, [:start, :finish] do |task, args|
DataMigration::UpdateUsername.new(start_id: args[:start], finish_id: args[:finish])
end
end
rake db:update_user[0, 10000]
rake db:update_user[10000, 20000]
# ...
Migrations are pending error while everything is up to date
The issue is your database reflects that migration is loaded but somehow the entry in schema_migrations either got deleted(accidentally or through migration rollback).
Steps to solve this issue:
Identify the migration(migration number) from db/migrations where study_agreements relation was introduced. Let's say it is 1234
Now manually create an entry in schema_migrations table in your DB. For example in MySQL you can do "INSERT INTO schema_migrations (version) values(1234)".
Another solution is: Run rake db:migrate after commenting the change or up method of your migration in which study_agreements relation was introduced.
How to skip rails migrations after creating database from dump
If you're restoring a database from a dump, the schema_migrations
table should restore along with the rest of the tables.
This seems to indicate your schema_migrations
table may not be getting backed up which would lead to the problem you have now.
The ideal solution would be to restore a backup that has all the tables in it correctly -- including schema_migrations
.
Even if you decide to find a way around this in the short-term, in the long-term the correct solution is to modify your backup scripts to get all the tables you need, including schema_migrations
.
In terms of what to do now, the ideal solution is probaby to backup just that one table (schema_migrations
) from your database and import that data into the database you're trying to load now. Then your migrations should no longer be pending.
Doing that with a simple table dump and load script should be fine. The simple postgres gui PgAdmin ( http://www.pgadmin.org/ ) may also provide some basic tools for dumping then loading a single table.
Related Topics
Find() with Nil When There Are No Records
How to Get Elapsed Time in Milliseconds in Ruby
Is There a Rails Console Command (Rails 3+) to Reload Changed Code
How to Check Whether a Value in a String Is an Ip Address
Get Absolute (Base) Url in Sinatra
Why Alias_Method Fails in Rails Model
Millisecond Resolution of Datetime in Ruby
Verify Client Certificate Using Sslserver in Ruby
Ruby Compare Two Strings Similarity Percentage
The Encoding That Notepad++ Just Calls "Ansi", Does Anyone Know What to Call It for Ruby
Best Ruby Idiom for "Nil or Zero"
Embedding JSON Data into Yaml File
Conditional Key/Value in a Ruby Hash
How to Avoid Putting the Magic Encoding Comment on Top of Every Utf-8 File in Ruby 1.9
Rails: Copying Attributes from an Object to Another Using the "Attributes" Method
How to Reverse Ruby's Include Function
How to Add MAC-Specific Gems to Bundle on MAC But Not on Linux