66

After creating a migration file with rails generate migration AddClientToUser I can edit my migration file like so:

class AddClientToUser < ActiveRecord::Migration
  def self.up
    change_table :users do |t|
      t.references :client
    end
  end

  def self.down
    change_table :users do |t|
      t.remove :client_id
    end
  end
end

Is this the correct way to reverse the reference column added in the migration?

Matt Connolly
  • 9,757
  • 2
  • 65
  • 61

4 Answers4

85

Rails 4.2.1

rails g migration RemoveClientFromUsers client:references

Will generate a migration similar:

class RemoveClientFromUser < ActiveRecord::Migration
  def change
    remove_reference :users, :client, index: true, foreign_key: true
  end
end

In addition, one is at liberty to add another or other reference(s) by adding:

add_reference :users, :model_name, index: true, foreign_key: true

within the very change method. And finally running rake db:migrate after saving the changes to the migration, will produce the desired results.

Zeeng
  • 1,155
  • 9
  • 13
48

that is right! and you could also go with:

  def self.down
      remove_column :users, :client_id
  end
Daniel
  • 2,989
  • 2
  • 25
  • 26
  • Great to know! I wasn't sure if there was some special Foreign Key magic that was made with the reference that would not be cleanly disposed of when the column was simply removed. But wouldn't your example be just `remove_column` not `t.remove_column` ?? – Matt Connolly Apr 13 '11 at 13:04
  • 9
    You can also now use the remove_references syntax. – Binary Phile Aug 26 '12 at 04:41
  • 5
    @BinaryPhile: `remove_reference` (singular) instead of `remove_references` – sampi Nov 25 '15 at 18:14
  • @sampi In '12 I believe that was the only api, now singular and plural are both acceptable: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/remove_reference – Binary Phile Nov 25 '15 at 19:13
  • Just a note that if you specify all of the details, as in [Zeeng's answer](https://stackoverflow.com/a/43689274/9140970), this migration will be reversible. – therealrodk Jun 03 '22 at 19:36
27

After rails 4 you can do the following

class AddClientToUser < ActiveRecord::Migration
  def change
    add_reference :users, :client, index: true
  end
end

It will handle the up and the down for you, as well as creating a foreign key index. You can also use remove_reference to do the opposite.

danielcooperxyz
  • 960
  • 1
  • 13
  • 28
Ryan
  • 9,340
  • 5
  • 39
  • 42
  • 1
    I've tried this on `rails@4.2.5` with the adapter `mysql2@0.4.2` and it does not work. It throws `needed in a foreign key constraint` mysql error. :( – mariowise Jan 24 '16 at 01:52
2

With Rails 4 you can just type:

$ rails generate migration AddClientRefToUser client:references

in the console and this will make the same that Ryan said.

xhenryx14
  • 704
  • 6
  • 10