65

I'm wondering how I can add associations to my models. Suppose, I generate two models

rails generate model User
rails generate model Car

Now I want to add an associations so that the models acquire the form

class User < ActiveRecord::Base
  has_many :cars
end
class Car < ActiveRecord::Base
  belongs_to :user
end

The question is: how to apply this modification by migrations in order to obtain cars_users table in the database? I'm planning to use that table in my code.

Andrew
  • 2,148
  • 5
  • 23
  • 34
  • 7
    you have no need for a `cars_users` table since you don't have a many-to-many relationship. – Zippie Mar 13 '13 at 12:19

4 Answers4

85

belongs_to association expect an association_id column in its corresponding table. Since cars belongs_to user, the cars table should have a user_id column. This can be accomplished 2 ways.

first, you can generate the column when you create the model

rails g model car user_id:references

or just add the user_id after you create the model like Richard Brown's answer. Be careful that if you use integer instead of references, you'd have to create the index yourself.

rails g migration add_user_id_to_cars user_id:integer

then in the generated migration, add

add_index :cars, :user_id

UPDATE:

As Joseph has mentioned in the comments, the need to add the index manually has already been addressed in the current version of Rails. I think it was introduced in Rails 4. You can read more of it in the official Rails guide for migrations. The gist of it is running the following generator

bin/rails g migration add_user_to_cars user:references

will create a migration with a line similar to

add_reference :cars, :user, index: true

This will add a user_id column to the cars table and it will also mark that column to be indexed.

RonU
  • 5,525
  • 3
  • 16
  • 13
jvnill
  • 29,479
  • 4
  • 83
  • 86
  • just curiosity: what if between the models there were has_and_belongs_to_many association. Who would be then responsible for creation of cars_users table? Me, Ruby on Rails or somebody else? – Andrew Mar 13 '13 at 17:05
  • 3
    you. habtm join tables don't need a class but still need the table and you need to create a migration for that :) – jvnill Mar 13 '13 at 19:04
  • 3
    Instead of doing this in two steps, you can add references after model creation like so: `rails g migration addUserReferencesToCars user:references`. This takes care of adding `user_id` to `cars` and making it an index in one shot. – Joseph Feb 19 '15 at 16:44
21

Following @jvnill's explanation in rails 4 (and maybe in rails 3.2 too) you can do it like this too (avoiding the id parts and remembering the exact convetions):

rails g migration AddUserToCar user:references

Which will create the following migration, taking care of both adding the column and index with all correct conventions:

class AddUserToCar < ActiveRecord::Migration
  def change
    add_reference :cars, :user, index: true
  end
end

At the end as always run the migration:

rake db:migrate

View your schema.rb to view the new index and user_id column.

K M Rakibul Islam
  • 33,760
  • 12
  • 89
  • 110
SimonW
  • 6,175
  • 4
  • 33
  • 39
10

Generate a migration to create the association:

rails g migration AddUserIdToCars user_id:integer
rake db:migrate
Richard Brown
  • 11,346
  • 4
  • 32
  • 43
1

Migration file:

class Createuser < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :name
    end

    create_table :cars do |t|
      t.belongs_to :user, index: true
      t.varchar(255) :model
      t.varchar(255) :color
    end
  end
end
vinoth
  • 145
  • 8