【问题标题】:Rails 5: ActiveRecord query last object in a joined table with OR conditionRails 5:ActiveRecord 使用 OR 条件查询连接表中的最后一个对象
【发布时间】:2017-04-28 09:49:53
【问题描述】:

我需要一些帮助来查询这里(Rails 5.1)。我有一个名为Verification (belongs_to :verifiable, polymorphic: true) 的多态关联对象。其他对象,如Comment,可以有verifications (has_many :verifications, as: :verifiable),最后一个(按id 排序)被认为是当前的。 Verification 有一个枚举属性 status。我需要检索具有特定user_id(当前用户之一)或当前(即最后一个)具有正确状态的验证对象(例如approved)的cmets。

所以,我正在尝试:

self.where(user_id: user.id).or(self.joins(:verifications).limit(1).where(verifications: { status: 'approved' }))

但是 Rails 给了我以下错误:

Relation passed to #or must be structurally compatible. Incompatible values: [:joins, :references, :limit]

我该怎么办?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-5 ruby-on-rails-5.1


    【解决方案1】:

    我无法使其仅在一个查询中工作(我的 Arel 尝试失败)。所以希望以下内容就足够了(经过测试):

    latest_verification_ids = Verification.group(:verifiable_id).maximum(:id).values
    
    # SELECT MAX("verifications"."id") AS maximum_id, "verifications"."verifiable_id" AS verifications_verifiable_id FROM "verifications" GROUP BY "verifications"."verifiable_id"
    
    comments_whose_user_id_is_user_id_or_whose_last_verification_is_approved =
      Comment
        .where(user_id: user_id)
        .or(
          Comment.where(id:
            Comment.joins(:verifications)
              .where(
                verifications: {
                  id: latest_verification_ids,
                  status: 'approved'
                }
              )
          )
        )
    
    # SELECT "comments".* FROM "comments" WHERE ("comments"."user_id" = ? OR "comments"."id" IN (SELECT "comments"."id" FROM "comments" INNER JOIN "verifications" ON "verifications"."verifiable_id" = "comments"."id" AND "verifications"."verifiable_type" = ? WHERE "verifications"."id" IN (4, 2) AND "verifications"."status" = ?))  [["user_id", 1], ["verifiable_type", "Comment"], ["status", "approved"]]
    

    【讨论】:

    • 谢谢,杰阿!这行得通,但有一个警告:它只给出 x 个对象(由于 limit(x) 参数)。如果省略此参数,则此查询会为所有评论提供至少一个具有所需状态的验证。但我只需要检查带有where(verifications: {status: 'approved'}) 条件的每个 评论的第一次验证。有什么想法吗?
    • 我删除了限制 (1)。即使将其删除,它也应该已经正常工作。至于性能,我还不太确定取消限制是否会产生更慢的影响。
    • 不幸的是,删除它会检查所有验证,如果它发现至少有一个满足条件 - 包括结果中的评论。如果您有测试模型,您可以自己尝试。添加几个验证并以不同的组合更改它们的状态证明了这一点。必须有一种方法可以只从加入的集合中检索第一个对象,但我想不通......
    • 哦,我以为您打算获取所有至少具有一次验证的 cmets(具有状态 == '已批准'),但似乎您只想要具有最后验证的 cmets(具有状态 == '得到正式认可的')。我正在更新我的答案。
    猜你喜欢
    • 2015-12-21
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    相关资源
    最近更新 更多