【问题标题】:Rails scope with complex SQL Statement including OR具有复杂 SQL 语句的 Rails 范围,包括 OR
【发布时间】:2015-05-05 17:31:43
【问题描述】:

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

所以我的问题,最后:

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 这不可能!说真的,这些东西是不干燥且不易阅读的方式:(
    • 鉴于 Rails+ActiveRecord / Arel / Squeel / Metawhere 等的当前状态,我认为它比替代方案更容易阅读。
    【解决方案2】:

    警告,我不知道权威(我更喜欢 acl9 的更简单的 DSL 方法),所以我只是真正为你转换你的查询,你通常可以让 Rails 给你一个 LEFT JOIN 和 @ 987654323@,你可以用这个小技巧来搞定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)
      )}
    

    【讨论】:

    • 感谢您的回答!不能按预期工作。这会产生SELECT "projects".* FROM "projects" WHERE (("projects"."owner_id" = $1 OR "projects"."is_public" = 't') OR "projects"."receiver_id" = 1633) 然后导致异常,因为项目没有接收者。控制台错误:PG::UndefinedColumn: ERROR: column projects.receiver_id does not exist -> LINE 1: ...wner_id" = $1 OR "projects"."is_public" = 't') OR "projects"...
    • 哦,对不起,我没有注意到那张桌子是不同的。我已经编辑了查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 2011-11-05
    • 2014-10-10
    • 1970-01-01
    相关资源
    最近更新 更多