我有一个User
和MeetOption
表。这是一个多对多的关系,我可以使用create_join_table命令创建一个连接表:
rails g migration CreateJoinTableUsersMeetOptions users meet_options
这会生成一个迁移文件:
class CreateJoinTableUsersMeetOptions < ActiveRecord::Migration[5.0]
def change
create_join_table :users, :meet_options do |t|
# t.index [:user_id, :meet_option_id]
# t.index [:meet_option_id, :user_id]
end
end
end
我还使用has_and_belongs_to_many
class User < ActiveRecord::Base
has_and_belongs_to_many :meet_options
#More codes below
end
class MeetOption < ApplicationRecord
has_and_belongs_to_many :users
end
该关联工作正常,我可以在Rails控制台中查询例如user.meet_options
。
我的问题是:联合MeetOptionsUsers
表没有模型,那么我该如何添加记录呢?现在,我必须使用GUI数据库软件(Postico)手动添加行,即user_id = 1; meet_option_id = 2
。
有没有办法在Rails控制台中添加MeetOptionUser.create(user_id: 1, meet_option_id: 2)
等记录,就像有与之关联的ActiveRecord模型一样?
答案 0 :(得分:6)
使用has_and_belongs_to_many
关系,您应该能够使用常规的Active Record关联方法将Users
和MeetOptions
链接在一起。您不应该直接操作连接表。 Rails会为您解决这个问题。 Ruby on Rails Guide has_and_belongs_to_many Association Reference列出了此关联自动创建的所有有用方法。
以下是一些您可能会觉得有用的方法。
collection<<(object,..)
会将一个或多个对象添加到连接表中。例如:
@user.meet_options << @meet_option
通过在联接表中添加适当的条目,上述内容会将提供的@meet_option
记录与@user
相关联。在这种情况下,带有user_id: @user.id
和meet_option_id: @meet_option.id
的记录将添加到连接表中。反过来完成同样的事情:
@meet_option.users << @user
另一种有用的方法是collection.delete(object,...)
。这允许您从连接表中删除关联。它不会删除关联的对象。例如:
@user.meet_options.delete @meet_option
以上将删除@user
和@meet_option
之间的关联,方法是删除连接表中的相应记录。但是,它不会从@user
表中删除users
,也不会从@meet_option
表中删除meet_options
。
collection.destroy(object,...)
与collection.delete(object,...)
完全相同。
collection=(objects)
将使集合仅包含所提供的对象,方法是根据需要在连接表中添加或删除。
此协会中还有许多其他使用方法。我建议您查看已关联的guide。使用这些方法,您应该能够管理连接表而无需直接操作它。让Rails和Active Record为你工作。
最后的想法
如果您希望通过连接模型更直接地访问连接表,则不应使用has_and_belongs_to_many
关联。您可能希望在连接表中添加更多属性,或者希望在连接模型本身上进行验证或回调。在这种情况下,您应该使用has_many :through association代替。 This blog post了解如何进行设置。