Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write conditional migrations in rails?

Tags:

I am looking for ways to write migrations in rails that can be executed against the database many times without failing.

For instance let say I have this migration:

class AddUrlToProfile < ActiveRecord::Migration   def self.up     add_column :profile, :url, :string   end    def self.down     remove_column :profile, :url   end end 

If the url column already exists in the Profile table (if the schema.rb has been modified unexpectedly for instance), my migration will fail saying that it's a duplicate!

So how to execute this migration only if it has to?

Thanks

like image 262
Amokrane Chentir Avatar asked Feb 12 '11 21:02

Amokrane Chentir


People also ask

How do I run a specific migration in rails?

To run a specific migration up or down, use db:migrate:up or db:migrate:down . The version number in the above commands is the numeric prefix in the migration's filename. For example, to migrate to the migration 20160515085959_add_name_to_users. rb , you would use 20160515085959 as the version number.

What is db migration in rails?

A Rails migration is a tool for changing an application's database schema. Instead of managing SQL scripts, you define database changes in a domain-specific language (DSL). The code is database-independent, so you can easily move your app to a new platform.

How do I run a database migration in Ruby on Rails?

Rails Migration allows you to use Ruby to define changes to your database schema, making it possible to use a version control system to keep things synchronized with the actual code. Teams of developers − If one person makes a schema change, the other developers just need to update, and run "rake migrate".


1 Answers

You can do something like this:

class AddUrlToProfile < ActiveRecord::Migration   def self.up     Profile.reset_column_information     add_column(:profile, :url, :string) unless Profile.column_names.include?('url')    end    def self.down     Profile.reset_column_information     remove_column(:profile, :url) if Profile.column_names.include?('url')   end end 

This will reset the column information before it begins - making sure that the Profile model has the up-to-date column information from the actual table. It will then only add the column if it doesn't exist. The same thing happens for the down function, but it only removes the column if it exists.

If you have multiple use cases for this you could factor the code out into a function and re-use that in your migrations.

like image 67
Pan Thomakos Avatar answered Oct 22 '22 09:10

Pan Thomakos