您需要添加一个单独的连接表,其中只包含restaurant_id
和user_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
;它可以防止创建主键):
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
会自动检测向前或回滚迁移,不需要使用up / down。
Rails 5
create_join_table :restaurants, :users do |t|
t.index [:restaurant_id, :user_id]
end
注意:还有一个自定义表名的选项,可以作为参数传递给create_join_table,名为
table_name
。来自
文档
默认情况下,联接表的名称来自于提供给create_join_table的前两个参数的字母顺序的并集。要自定义表的名称,请提供一个:table_name选项:
restaurant_id
,第一个将是最快的。如果你在搜索user_id
,第二个将有所帮助。如果你同时搜索两者,则我认为数据库聪明到只需要一个。所以我想第二个不用复合索引也可以。这只是一个例子。这是一个Rails问题,所以在DB部分发布将得到更完整的答案。 - Dexrails g migration create_restaurants_users
,末尾不需要加上"table"。 - Fa11enAngel