如何order("created_at desc")
几个月?
本月内的文章按降序排列,但不是月份本身。
控制器
def archives
@posts = Post.order("created_at desc")
@posts_by_months = @posts.group_by { |t| t.created_at.beginning_of_month }
end
查看
<% @posts_by_months.sort.each do |month, posts| %>
<%= month.strftime('%b') %>
<% for post in posts %>
<%= post.title %>
<% end %>
<% end %>
答案 0 :(得分:1)
按月份数字排序时,您必须进行一些明确的转换:
在控制器中:
@posts_by_months = @posts.group_by { |t| t.created_at.beginning_of_month }.
sort_by { |k, _| k.strftime('%-m').to_i }.reverse
@posts_by_months.each { |month, posts| puts month.strftime('%b') } ;
=> Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
此处k.strftime('%-m')
提取月份编号而不填充字符串,to_i
将其转换为数字。如果没有转换,sort_by
将应用词汇排序,而不是所需要的。
sort_by
的结果不是散列而是二维数组。但这不会影响视图代码。
答案 1 :(得分:1)
使用Enumerable#inject
http://ruby-doc.org/core-2.3.1/Enumerable.html#method-i-inject:
@posts_by_months = @posts_by_months.inject({}) do |h,(k,v)|
h[k] = v.sort do |x,y|
y.created_at <=> x.created_at
end
h
end
例如:
irb(main):054:0> hash = @posts_by_months.inject({}) {|h,(k,v)| h[k] = v.sort {|x,y| y.created_at <=> x.created_at}; h}
#=> […]
irb(main):055:0> pp hash.first.map(&:created_at)
[Wed, 08 Jun 2016 22:26:34 UTC +00:00,
Wed, 08 Jun 2016 21:49:49 UTC +00:00,
Wed, 08 Jun 2016 18:30:44 UTC +00:00,
Wed, 08 Jun 2016 18:25:40 UTC +00:00]
<强>更新强>
通过控制器为Rails视图工作。
# app/controllers/website_controller.rb
class WebsiteController < ApplicationController
def test
@posts = Post.order("created_at desc")
@posts_by_months = @posts.group_by {|t| t.created_at.beginning_of_month}
@posts_by_months = @posts_by_months.inject({}) do |h,(k,v)|
h[k] = v.sort do |x,y|
y.created_at <=> x.created_at
end
h
end
render(:layout => false, :template => 'website/test')
end
end
使用HAML(http://haml.info)模板:
# app/views/website/test.html.haml
- @posts_by_months.sort.each do |month, posts|
= month.strftime('%b')
%br
%ul
- for post in posts
%li
= post.title
答案 2 :(得分:1)
以防您使用PostgreSQL:
@posts = Post.select('extract(month from created_at) as month, posts.*').order('month DESC, created_at DESC').group_by(&:month)
@posts.each do |month, posts|
puts "This is the month: #{Date::MONTHNAMES[month]}"
puts "And this is array of posts: #{posts}"
end