我有一个帖子模型和一个 View 模型(记录用户对每个帖子的 View ),如下所示:
class View < ActiveRecord::Base
belongs_to :user, :class_name => 'User'
belongs_to :post, :class_name => 'Post'
validates_uniqueness_of :user_id, :scope =>:post_id
end
每个帖子都有一个名为“special”的 bool 字段。
我想获取具有以下排序条件的所有帖子:
- 如果某个帖子是“特殊”的且未被当前用户查看(例如 user_id=2),则该帖子应显示在结果的顶部,内部按 ID 降序排序。
- 根据帖子的 ID 字段对所有其他帖子(非特殊帖子和查看过的特殊帖子)进行排序。
不知道我是否可以以及如何做到这一点。
首先,我尝试了以下查询:
posts = Post.order("(case when special = true then 'special desc, id desc' else 'id desc' end)")
但它的行为方式很有趣:返回顶部的所有特殊帖子,然后是常规帖子,但 id 按升序排序。
我在这里缺少什么?另外,如何将 join(用于 View 表)与如此复杂的 order by 子句一起使用?我尝试为此编写一条 SQL,但也遇到了困难!给我一些启发:)
P.S 我是 Rails 新手,仍在学习中。
最佳答案
您发布的代码是,对于每一行计算 2 个字符串文字之一,并根据该文字进行排序,这就是您没有获得所需示例的原因。 我会做类似的事情
Post.order('special desc, id desc')
由于 Rails 在 MySQL 中将 bool 字段存储为 0/1,因此会将特殊帖子排在非特殊帖子之前。
向此添加 View 并不会改变很多:您需要左连接 View 表并执行类似的操作
Post.joins('left join views on posts.id=post_id and user_id=2').order(' ( views.id is null && special) desc, id desc')
is null
检测是否找到 View ,然后将其与帖子的特殊性进行“and-ed”。
关于mysql - 多列的条件排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11595400/