【问题标题】:Order comments from certain users first, then by comment score首先从某些用户的评论中排序,然后是评论分数
【发布时间】:2018-10-01 19:16:28
【问题描述】:

在 Rails 4 项目中,我有 articleshas_many comments

我试图在一篇按评论score(评论表中的整数列)排序的文章下显示一个 cmets 列表,但其中 首先显示来自少数用户的 cmets(例如管理员和模组)。这些用户将作为 user_ids 数组传递给查询(user_id 也是评论表中的一列):

class Comment < ActiveRecord::Base
  # article_id  :integer
  # user_id     :integer
  # score       :integer

  belongs_to :article
  belongs_to :user

  scope :by_users, -> (user_ids) { order("user_id IN (?), score DESC", user_ids) }

因此:

some_article.comments.by_users([1,2,3])

这个范围给出了一个语法错误,我不能很好地计算出一个对 cme​​ts 排序的查询,以便返回所有文章的 cmets,首先显示来自传递数组中的 user_id 的用户,然后再按评论分数排序.

更新:

mahemoff 伟大的条件思想不适用于 Postgres,但导致了这种无效的尝试:

scope :by_users, -> (user_ids) { order("case when (user_id IN (?)) then 0 else 1 end, score DESC", user_ids) }

这给了我一个与占位符 ? 相关的 PostgreSQL 语法错误,我无法修复。

【问题讨论】:

    标签: sql ruby-on-rails postgresql ruby-on-rails-4 activerecord


    【解决方案1】:

    mahemoff & mu is too short的帮助和建议下,这是我的工作范围:

    scope :by_users, -> (user_ids) { order([sanitize_sql("case when (user_id IN (#{user_ids.join(',')})) then 0 else 1 end"), "score DESC" ]) }
    

    这有点不完美,因为 Rails 的 order 显然不支持 ? 占位符,所以我使用了字符串插值并且(即使 user_ids 不是用户暴露的)清理了 sql。

    ...然而,一个令人沮丧的问题, 是不可能使用.last 来检索最终记录。 some_article.by_users[1,2].last 现在会抛出一个错误,因为 AR 无法确定在哪里颠倒排序:

    ORDER BY case when (user_id IN (1 DESC, 2)) then 0 else 1 end DESC, score ASC LIMIT 1
    

    叹息...

    【讨论】:

      【解决方案2】:

      试试这个:

      class Comment < ActiveRecord::Base
        scope :by_users, -> (user_ids) { order("if(user_id IN (#{ids.join ','}), 0, 1), score DESC") }
      

      【讨论】:

      • (1) PostgreSQL 没有这样的if 函数,CASE 表达式是可移植的。 (2) ActiveRecord 不想要order([expr_with_placeholders, value]) 以便在order 调用中使用占位符吗?
      • mu 是正确的,Postgres 使用 case 开关进行条件逻辑 - 使用 mahemoff 的想法给了我这个无效的尝试:order("case when (user_id IN (?)) then 0 else 1 end, score DESC", user_ids) 问题似乎出在 ? 占位符上对于user_ids...
      • @dj。然后,您可以尝试使用数组,就像 mu 建议的那样。此外,如果真的很头疼,您也不必必须使用占位符。至少在开发中,您可以尝试仅使用字符串插值,例如 user_id in (#{ids.join ','}),然后担心以后对其进行清理。
      • 嗯...Rails 中的order 不能使用? 占位符,例如where 子句。
      猜你喜欢
      • 2012-11-01
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 2011-12-18
      • 2020-01-14
      相关资源
      最近更新 更多