Rails范围包含复杂的SQL语句,包括OR

时间:2015-03-04 16:14:25

标签: ruby-on-rails postgresql ruby-on-rails-4 scopes pundit

我现在正在开发一个小型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

所以我的问题,最后:

是否有一种优雅的方式来做我现在正在做的事情? 它感觉很难看,而且不像铁轨一样!

2 个答案:

答案 0 :(得分:0)

警告,我不知道专家(我更喜欢acl9更简单的DSL方法),所以我只是真的为你转换你的查询,你通常可以让Rails给你一个{{1使用LEFT JOIN,您可以使用这个小技巧来获得一个整洁的includes()

OR

答案 1 :(得分:-1)

根据我的经验,您现在拥有的解决方案是最好的解决方案。你可以使用像Arel,Squeel或MetaWhere这样的东西来Ruby-fy你的SQL字符串,但那些更复杂。

如果这符合您的要求,我不会过于担心它会导致更多Rails-y。"