Rails has_and_belongs_to_many迁移

时间:2011-07-03 05:50:42

标签: ruby-on-rails ruby-on-rails-3 migration has-and-belongs-to-many

我有两个模型restaurantuser,我想要执行has_and_belongs_to_many关系。

我已进入模型文件并添加了has_and_belongs_to_many :restaurantshas_and_belongs_to_many :users

我认为此时我应该可以使用Rails 3执行某些操作:

rails generate migration ....

但我尝试的一切似乎都失败了。我确信这是非常简单的我对rails很新,所以我还在学习。

4 个答案:

答案 0 :(得分:231)

您需要以字母顺序添加仅包含restaurant_iduser_id(无主键)的单独联接表。

首先运行迁移,然后编辑生成的迁移文件。

Rails 3

rails g migration create_restaurants_users_table

Rails 4

rails g migration create_restaurants_users

Rails 5

rails g migration CreateJoinTableRestaurantUser restaurants users

来自docs

  

还有一个生成器,如果JoinTable将生成连接表   是名称的一部分:


您的迁移文件(请注意:id => false;这是阻止创建主键的原因):

Rails 3

class CreateRestaurantsUsers < ActiveRecord::Migration
  def self.up
    create_table :restaurants_users, :id => false do |t|
        t.references :restaurant
        t.references :user
    end
    add_index :restaurants_users, [:restaurant_id, :user_id]
    add_index :restaurants_users, :user_id
  end

  def self.down
    drop_table :restaurants_users
  end
end

Rails 4

class CreateRestaurantsUsers < ActiveRecord::Migration
  def change
    create_table :restaurants_users, id: false do |t|
      t.belongs_to :restaurant
      t.belongs_to :user
    end
  end
end

t.belongs_to将自动创建必要的索引。 def change将自动检测转发或回滚迁移,无需上/下。

Rails 5

create_join_table :restaurants, :users do |t|
  t.index [:restaurant_id, :user_id]
end

注意:还有一个自定义表名的选项,可以作为参数传递给名为table_name的create_join_table。来自docs

  

默认情况下,连接表的名称来自的联合   前两个参数以字母顺序提供给create_join_table   订购。要自定义表的名称,请提供:table_name   选项:

答案 1 :(得分:29)

这里的答案很陈旧。从Rails 4.0.2开始,您的迁移使用create_join_table

要创建迁移,请运行:

rails g migration CreateJoinTableRestaurantsUsers restaurant user

这将生成以下内容:

class CreateJoinTableRestaurantsUsers < ActiveRecord::Migration
  def change
    create_join_table :restaurants, :users do |t|
      # t.index [:restaurant_id, :user_id]
      # t.index [:user_id, :restaurant_id]
    end
  end
end

如果您想对这些列编制索引,请取消注释相应的行,您就可以开始使用了!

答案 2 :(得分:24)

创建连接表时,请特别注意需要在迁移名称/类中以字母顺序列出两个表的要求。如果您的型号名称相似,这可能很容易让您感到困惑,例如: “abc”和“abb”。如果你要跑

rails g migration create_abc_abb_table

您的关系将按预期工作。你必须使用

rails g migration create_abb_abc_table

代替。

答案 3 :(得分:6)

对于HABTM关系,您需要创建一个连接表。只有连接表,该表不应该有一个id列。试试这次迁移。

def self.up
  create_table :restaurants_users, :id => false do |t|
    t.integer :restaurant_id
    t.integer :user_id
  end
end

def self.down
  drop_table :restaurants_users
end

您必须检查this relationship rails guide tutorials