我现在正在开发一个小型Rails项目。我使用Pundit授权控制器操作和内容。现在的工作是使用Pundit进行索引操作,并在我的控制器中使用Pundit的policy_scope
来获取用户可以看到的项目。
用户应该能够通过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
所以我的问题,最后:
是否有一种优雅的方式来做我现在正在做的事情? 它感觉很难看,而且不像铁轨一样!
答案 0 :(得分:0)
警告,我不知道专家(我更喜欢acl9更简单的DSL方法),所以我只是真的为你转换你的查询,你通常可以让Rails给你一个{{1使用LEFT JOIN
,您可以使用这个小技巧来获得一个整洁的includes()
:
OR
答案 1 :(得分:-1)
根据我的经验,您现在拥有的解决方案是最好的解决方案。你可以使用像Arel,Squeel或MetaWhere这样的东西来Ruby-fy你的SQL字符串,但那些更复杂。
如果这符合您的要求,我不会过于担心它会导致更多Rails-y。"