Ruby-on-rails Rails has_and_belongs_to_many 迁移

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6561330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:31:22  来源:igfitidea点击:

Rails has_and_belongs_to_many migration

ruby-on-railsruby-on-rails-3migrationhas-and-belongs-to-many

提问by dbslone

I have two models restaurantand userthat I want to perform a has_and_belongs_to_many relationship.

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

I have already gone into the model files and added the has_and_belongs_to_many :restaurantsand has_and_belongs_to_many :users

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

I assume at this point I should be able to do something like with Rails 3:

我假设此时我应该能够用 Rails 3 做一些事情:

rails generate migration ....

but everything I have tried seems to fail. I'm sure this is something really simple I'm new to rails so I'm still learning.

但我尝试过的一切似乎都失败了。我确信这是非常简单的事情,我是 Rails 的新手,所以我仍在学习。

回答by Dex

You need to add a separate join table with only a restaurant_idand user_id(no primary key), in alphabetical order.

您需要按字母顺序添加一个只有一个restaurant_iduser_id(没有主键)的单独连接表。

First run your migrations, then edit the generated migration file.

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

Rails 3

导轨 3

rails g migration create_restaurants_users_table

Rails 4:

轨道 4

rails g migration create_restaurants_users

Rails 5

导轨 5

rails g migration CreateJoinTableRestaurantUser restaurants users

From the docs:

文档

There is also a generator which will produce join tables if JoinTable is part of the name:

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



Your migration file (note the :id => false; it's what prevents the creation of a primary key):

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

Rails 3

导轨 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

导轨 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_towill automatically create the necessary indices. def changewill auto detect a forward or rollback migration, no need for up/down.

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

Rails 5

导轨 5

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

Note: There is also an option for a custom table name that can be passed as a parameter to create_join_table called table_name. From the docs

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

By default, the name of the join table comes from the union of the first two arguments provided to create_join_table, in alphabetical order. To customize the name of the table, provide a :table_name option:

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

回答by Jan Klimo

The answers here are quite dated. As of Rails 4.0.2, your migrations make use of create_join_table.

这里的答案已经过时了。从 Rails 4.0.2 开始,您的迁移使用create_join_table.

To create the migration, run:

要创建迁移,请运行:

rails g migration CreateJoinTableRestaurantsUsers restaurant user

This will generate the following:

这将生成以下内容:

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

If you want to index these columns, uncomment the respective lines and you're good to go!

如果您想为这些列建立索引,请取消对相应行的注释,您就可以开始了!

回答by shacker

When creating the join table, pay careful attention to the requirement that the two tables need to be listed in alphabetical orderin the migration name/class. This can easily bite you if your model names are similar, e.g. "abc" and "abb". If you were to run

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

rails g migration create_abc_abb_table

Your relations will notwork as expected. You must use

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

rails g migration create_abb_abc_table

instead.

反而。

回答by Mohit Jain

For HABTM relationships, you need to create a join table. There is only join table and that table should not have an id column. Try this migration.

对于 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

You must check this relationship rails guide tutorials

你必须检查这个关系 rails guide tutorials