0

我现在正在做一个小型的 Rails 项目。我正在使用 Pundit 来授权控制器操作和内容。现在的工作是使用 Pundit 进行索引操作,并policy_scope在我的控制器中使用 Pundit 来获取用户可以看到的项目。

用户可以通过 3 种方式查看项目: - 他是所有者 - 他被邀请 - 项目是公开的

我现在尝试了几种解决方案,但最终做了以下事情:

scope :public_or_involved, -> (user) { 
  joins('LEFT JOIN invitations ON invitations.project_id = projects.id').
  where('projects.is_public = TRUE OR projects.owner_id = ? OR invitations.reciever_id = ?', user.id, user.id) 
}

这是我得到类似“public_or_involved”的唯一方法来处理 project_policy.rb 中的以下权威范围:

class Scope
  attr_reader :user, :scope

  def initialize(user, scope)
    @user = user
    @scope = scope
  end

  def resolve
    scope.public_or_involved(user)
  end
end

所以我的问题,最后:

有没有一种优雅的方式来做我现在正在做的事情? 感觉很丑,不像铁轨!

4

2 回答 2

0

警告,我不知道权威(我更喜欢acl9更简单的 DSL 方法),所以我只是真正为你转换你的查询,你通常可以让 Rails 给你一个LEFT JOINwith includes(),你可以使用这个小技巧来更整洁OR

scope :public_or_involved,
  -> (user) { includes(:invitations).where(
    where( is_public: true, owner_id: user.id, invitations: { receiver_id: user.id } ).where_values.reduce(&:or)
  )}
于 2015-03-04T16:41:58.140 回答
-1

根据我的经验,您现在拥有的解决方案是最好的解决方案。您可以使用 Arel、Squeel 或 MetaWhere 之类的东西来对您的 SQL 字符串进行 Ruby-fy,但这些都会增加复杂性。

如果这符合您的要求,我不会太担心让它“更符合 Rails-y”。

于 2015-03-04T16:33:35.583 回答