If I create a new rails 3 migration with (for example)
rails g migration tester title:tester user:references
, everything works fine...however if I add a column with something along the lines of:
rails g migration add_user_to_tester user:references
the reference field is not recognised. In short, the question is: how do I add a referencing column to a rails migration from the command line?
If you are using the Rails 4.x you can now generate migrations with references, like this:
rails generate migration AddUserRefToProducts user:references
like you can see on rails guides
EDIT: This is an outdated answer and should not be applied for Rails 4.x+
You don't need to add references when you can use an integer id to your referenced class.
I'd say the advantage of using references instead of a plain integer is that the model will be predefined with belongs_to and since the model is already created and will not be affected when you migrate something existing, the purpose is kind of lost.
So I would do like this instead:
rails g migration add_user_id_to_tester user_id:integer
And then manually add belongs_to :user in the Tester model
Please note that you will most likely need an index on that column too.
class AddUserReferenceToTester < ActiveRecord::Migration
def change
add_column :testers, :user_id, :integer
add_index :testers, :user_id
end
end
user.testers
you can omit the index.
rails g migration ...
generated add_reference :installs, :device, index: true
which also creates the index.
With the two previous steps stated above, you're still missing the foreign key constraint. This should work:
class AddUserReferenceToTester < ActiveRecord::Migration
def change
add_column :testers, :user_id, :integer, references: :users
end
end
You can use references in a change migration. This is valid Rails 3.2.13 code:
class AddUserToTester < ActiveRecord::Migration
def change
change_table :testers do |t|
t.references :user, index: true
end
end
def down
change_table :testers do |t|
t.remove :user_id
end
end
end
c.f.: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table
down
method, I got ActiveRecord::IrreversibleMigration
when rolling back using Rails 3.2. I also had to change change
to up
.
Running rails g migration AddUserRefToSponsors user:references
will generate the following migration:
def change
add_reference :sponsors, :user, index: true
end
When adding a column you need to make that column an integer and if possible stick with rails conventions. So for your case I am assuming you already have a Tester and User models, and testers and users tables.
To add the foreign key you need to create an integer column with the name user_id (convention):
add_column :tester, :user_id, :integer
Then add a belongs_to to the tester model:
class Tester < ActiveRecord::Base
belongs_to :user
end
And you might also want to add an index for the foreign key (this is something the references already does for you):
add_index :tester, :user_id
That will do the trick:
rails g migration add_user_to_tester user_id:integer:index
You can add references to your model through command line in the following manner:
rails g migration add_column_to_tester user_id:integer
This will generate a migration file like :
class AddColumnToTesters < ActiveRecord::Migration
def change
add_column :testers, :user_id, :integer
end
end
This works fine every time i use it..
For Rails 4
The generator accepts column type as references (also available as belongs_to
).
This migration will create a user_id
column and appropriate index:
$ rails g migration AddUserRefToProducts user:references
generates:
class AddUserRefToProducts < ActiveRecord::Migration
def change
add_reference :products, :user, index: true
end
end
http://guides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration
For Rails 3
Helper is called references (also available as belongs_to
).
This migration will create a category_id
column of the appropriate type. Note that you pass the model name, not the column name. Active Record adds the _id
for you.
change_table :products do |t|
t.references :category
end
If you have polymorphic belongs_to
associations then references will add both of the columns required:
change_table :products do |t|
t.references :attachment, :polymorphic => {:default => 'Photo'}
end
Will add an attachment_id column and a string attachment_type
column with a default value of Photo
.
http://guides.rubyonrails.org/v3.2.21/migrations.html#creating-a-standalone-migration
Success story sharing