ChatGPT解决这个技术问题 Extra ChatGPT

Rails 3 migrations: Adding reference column?

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?


e
e382df99a7950919789725ceeec126

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


how do you specify a column name for the foreign key instead the auto generated name?
@jwill you can use polymorphic: user:references{polymorphic}.
@PauloFidalgo Can you explain a bit about how to do that? may be some guide of links? (talking about polymorphic)
d
dan-klasson

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


But that won't create the appropriate foreign key constraints on databases that support it, right?
No, afaik Rails never create foreign key restraints on the database unless you add plugins to do it for you.
just studying this post, pls how do i add the reference after all
remember to add the index with user:integer:index
Answer is dated, see @Paulo's answer for modern rails.
I
Itay Grudev

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

Why? Is this true for most belongs_to relationships?
It is indeed for performance reasons and comes in handy if you have a has_many/has_one on the other side of that belongs_to relation. If you are absolutely sure that you will not go through user.testers you can omit the index.
The rails g migration ... generated add_reference :installs, :device, index: true which also creates the index.
M
Martin Cabrera Diaubalick

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

This is the only actual answer here. The foreign key is the most critical part here
this should be marked as the correct answer since the questions asks for rails 3
g
gl03

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


change and down methods? aren't up and down methods instead?
@MaicolBen yes, and you can also just leave off the down method.
@MaicolBen Without the down method, I got ActiveRecord::IrreversibleMigration when rolling back using Rails 3.2. I also had to change change to up.
I
Itay Grudev

Running rails g migration AddUserRefToSponsors user:references will generate the following migration:

def change
  add_reference :sponsors, :user, index: true
end

Which version of Rails is this for?
Z
Zamith

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

m
masterweily

That will do the trick:

rails g migration add_user_to_tester user_id:integer:index

I like that this also adds the index that you will most likely want.
N
Neha

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..


s
shilovk

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