Rails has_and_belongs_to_many迁移
我有两个模型restaurant
和user
,我想执行一个has_and_belongs_to_many关系。
我已经进入模型文件,并添加了has_and_belongs_to_many :restaurants
和has_and_belongs_to_many :users
我认为在这一点上,我应该能够像Rails 3一样做:
rails generate migration ....
但是我所尝试的一切似乎都失败了。 我敢肯定,这是非常简单的东西我是新来的铁轨,所以我仍然在学习。
你需要添加一个单独的连接表,只有一个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
;这是阻止创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
你必须检查这个关系导轨教程