Rails 5:添加记录到没有模型的连接表(has_and_belongs_to_many)

时间:2017-11-05 20:29:05

标签: ruby-on-rails ruby rails-activerecord

我有一个UserMeetOption表。这是一个多对多的关系,我可以使用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

创建了用户和meet_option模型之间的关联
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模型一样?

1 个答案:

答案 0 :(得分:6)

使用has_and_belongs_to_many关系,您应该能够使用常规的Active Record关联方法将UsersMeetOptions链接在一起。您不应该直接操作连接表。 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.idmeet_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了解如何进行设置。