Rails:has_and_belongs_to_many 有 "master" 条记录

Rails: has_and_belongs_to_many with "master" record

我必须建模:UserPost。每个用户都可以 "pin"(添加到他的页面)任何 post,因此 user.posts 应该 return 所有添加的 post 和 post.users 应该 return 收藏 post 的所有用户。

此外,用户应该能够创建 post,因此每个 post 都有一个创建者("master" 用户),因此 post.user 应该 return 这个主用户(对于主用户,post 始终是 "pined")。

我的想法是像这样使用迁移

create_table :posts_users do |t|
  t.references :post, null: false, index: true
  t.references :user, null: false, index: true
  t.boolean :master, null: false, default: false
end

但是我应该如何在模型中指定关联?

has_and_belongs_to_many 方法实际上只是定义 has_many through 关系的快捷方式,它不是用于在中间连接 table 中存储任何附加数据的 suitable。将您的 posts_users 重命名为 pins,我认为它可以像这样工作:

class User < ActiveRecord::Base
  has_many :pins
  has_many :posts, through: :pins

  has_many :master_posts, -> {where pins: {master: true}},
    class_name: "Post", through: :pins, source: :post
end

class Pin < ActiveRecord::Base
  belongs_to :post
  belongs_to :user
end

class Post < ActiveRecord::Base
  has_many :pins
  has_many :users, through: :pins

  def user
    users.where(pins: {master: true}).first
  end
end

总体而言,它只是标准 has_many :through association you will encounter in almost every app. The interesting part is the master_posts association. You can about the passed options in the documentation(请参阅底部的 Options 部分)。

bob = User.create! name: "Bob"

bob.posts.create! title: "Title 1"
bob.posts.create! title: "Title 2"

bob.posts.pluck :title
# => ["Title 1", "Title 2"]

bob.master_posts.create! title: "Title 3"
bob.master_posts.create! title: "Title 4"

bob.master_posts.pluck :title
# => ["Title 3", "Title 4"]

bob.master_posts.last.user == bob
# => true