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

但是我所尝试的一切似乎都失败了。 我敢肯定,这是非常简单的东西我是新来的铁轨,所以我仍然在学习。

你需要添加一个单独的连接表,只有一个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 

从文档 :

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


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

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将自动创build必要的索引。 def change会自动检测转发或回滚迁移,不需要上/下。

Rails 5

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

注意:还可以select一个自定义表名称,该名称可以作为parameter passing给create_join_table,名为table_name 。 从文档

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

在创build连接表时,要特别注意两个表需要在迁移名称/类中按字母顺序排列的要求 。 如果您的模型名称相似,如“abc”和“abb”,这可以轻松地咬你。 如果你要跑步

 rails g migration create_abc_abb_table 

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

 rails g migration create_abb_abc_table 

代替。

这里的答案是相当过时的。 从Rails 4.0.2开始,你的迁移使用了create_join_table

要创build迁移,请运行:

 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 

如果你想索引这些列,取消注释各自的行,你很好去!

对于HABTM关系,您需要创build一个连接表。 只有连接表,该表不应该有一个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 

你必须检查这个关系导轨教程