Rollify Gem User has_many polls/roles 和 Poll 有很多回答者,只有一个管理员

Rollify Gem User has_many polls/roles and Poll has many answerers and only one admin

尝试与用户 has_many polls/roles 创建投票应用程序,但投票有很多回答者,只有一个管理员。

user.rb

class User < ApplicationRecord
  rolify
  has_many :polls, dependent: :destroy, through: :roles, source: :resource, source_type: :Poll
end

poll.rb

class Poll < ApplicationRecord
  resourcify

  # has_many :users, through: :roles, class_name: 'User', source: :users
  has_many :answerers, -> { where(:roles => {name: ::answerers}) }, through: :roles, class_name: 'User', source: :users
  belongs_to :admin, -> { where(:roles => {name: :admin}) }, through: :roles, class_name: 'User', source: :users
end

保持运行进入以下错误:

Unknown key: :through. Valid keys are: :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading, :autosave, :required, :touch, :polymorphic, :counter_cache, :optional, :default

错误是由poll.rb中的这一行引起的:

belongs_to :admin, -> { where(:roles => {name: :admin}) }, through: :roles, class_name: 'User', source: :users

你 运行 陷入了一个经典的误解,这是由于混淆了 belongs_tohas_one 的语义造成的。

A belongs_to 将外键列放在 this 模型 table 上。当您使用 belongs_to :admin 时,Rails 假定您有 polls.admin_id 列指向 admins.id.

belongs_to 关联从不间接,因此没有 through: 选项。 has_one 确实如此。

如果您想保证投票只能有一个管理员,您不想在这种特定情况下使用 Rolify,而是使用:

class Poll < ApplicationRecord
  resourcify
  # ...
  belongs_to :admin, class_name: 'User'
end

完全可以。虽然 Rolify 提供了一种添加角色的便捷方式,但并不是应用程序中的每个关联都应该强加到其中。直接 link 比通过两个连接 table 更有效,并保证只有一个值。

虽然您可能会想“如果我只使用 has_one 会怎么样?”。 has_one 不保证投票只有管理员 - 它只是将 LIMIT 1 添加到查询中。

Rolify 使用 users_roles HABTM 连接 table 来连接用户和角色,例如,您无法在不影响整个系统的情况下向 table 添加唯一性约束系统.