I'm trying to loop over my posts
and order('created_at DESC')
and sort
by pinned
(which is a boolean
) .
How is it possible to order
records by created_at
and sort
with pinned so pinned posts come on top.
I've tried with the following, but the sorting gets massed up and is no longer ordered by created_at
or if I try to add the sort_by
at the end, the pagination
would stop work.
posts = Post.active.order('created_at DESC').page(params[:page]).per(25)
@posts = posts.sort_by { |post| [post.pinned ? 0 : 1, post] }
I have also tried the following with no luck:
@posts = Post.active.order('created_at DESC').page(params[:page]).per(25)
// In my view
- @posts.sort_by { |post| [post.pinned ? 0 : 1, post] }.each do |post|
This will produce an error for the pagination
posts = Post.active.order('created_at DESC').sort_by { |post| [post.pinned ? 0 : 1, post] }.page(params[:page]).per(25)
Any tips are appreciated!
Max 的回答是要走的路,他的评论中唯一缺少的是将它包装在 Arel.sql 中
posts = Post.active.order(Arel.sql("CASE WHEN pinned THEN 0 ELSE 1 END"), "created_at DESC"))
As an alternative you can construct the query with Arel::Nodes::Case
instead of a string:
class Post < ApplicationRecord
def self.pinned_on_top
kase = Arel::Nodes::Case.new(arel_table[:pinned])
order(
kase.when(1).then(0).else(1)
)
end
end
# Given the following
Post.create(pinned: true) # id: 1
Post.create(pinned: false) # id: 2
Post.create(pinned: true) # id: 3
Post.pinned_on_top.order(created_at: :desc).ids # 3, 1, 2
The key advantage is portability.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.