2016-07-04 83 views
1

如何order("created_at desc")个月?如何“desc”订购group_by?

本月内的文章按降序排列,但不是月份本身。

控制器

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 %> 
+1

这是为'Post.order一样简单( 'MONTH(created_at),created_at desc')'? –

回答

1

Enumerable#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] 

UPDATE

Works的导轨经由控制器查看。

# 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 

Screenshot of "test.html.haml"

+0

感谢您的帮助!我一直在寻找的东西,但添加到控制器 –

+0

我刚刚更新了我的答案。我相信你可以在控制器中使用 - 我还没有测试过。 – SoAwesomeMan

+0

@ AnthonyGalli.com刚刚测试过它并在控制器中工作。结果更新答案。 – SoAwesomeMan

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的结果不是散列,而是二维数组。尽管如此,这并不影响视图代码。

+0

感谢Nic!我无法让它工作。月份仍然按升序显示 –

+0

对不起,修正了这个例子。 –

+0

对不起,仍然无法正常工作:/ –

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