显示博客帖子的每月存档

时间:2011-03-27 03:29:47

标签: ruby arrays hash datamapper

我正在尝试为我的博客创建一个“存档”页面。它应列出所有博客标题,按逆序排序,按月分组。

我正在使用DataMapper,它没有像MySQL这样的DATE_FORMAT函数,这意味着我不能简单地在查询中进行分组。因此,除了用普通的Ruby做所有艰苦的工作外,我没有别的办法。

这就是我目前所拥有的:

# GOOD: order of posts within the months are correct
# BAD: order of months is random

@posts = Post.published(:order => :published_at.desc)

@months = {}
@posts.each do |post|
  month_year = post.published_at.strftime("%B %Y")
  @months[month_year] = [] unless @months.has_key? month_year
  @months[month_year] << post
end

查看:

.archive
  - @months.each do |month, posts|
    %h2= month
    %ol
      - posts.each do |post|
        = partial(post)

这样做我想要的除了几个月的顺序搞砸了,因为它们包含在一个哈希中。 (我在Ruby 1.8上,所以散列的顺序实际上是随机的。)

如何使月份的顺序正确?我可能需要使用数组,但我无法弄清楚代码的其余部分是什么样的。

2 个答案:

答案 0 :(得分:1)

# Creating random data to similate your DataMapper array
require 'date'
require 'ostruct'

posts = 10.times.inject([]) {|s,i| s << OpenStruct.new(:id => i, :published_at => Date.parse("2010-#{rand(11)+1}-#{rand(25)+1}"), :title => "title #{i}")}

# Your code starts here
ordered_posts = posts.inject({}) do |s,p|
  ym = p.published_at.strftime('%Y-%m')
  s.merge(s[ym] ? {ym=>s[ym]<<p} : {ym=>[p]})
end.sort {|a,b| b[0] <=> a[0]}

# then in your view do
ordered_posts.each do |op|
  puts op[0][-2,2] # your %h2 line
  op[1].sort {|a,b| b.published_at <=> a.published_at}.each do |p|
    puts "   #{p.published_at.strftime('%m/%d/%y')}-#{p.title}" # your partial(posts) line
  end
end

产生

wesbailey@feynman:~/code_katas> ruby blogs.rb 
11
   11/10/10-title 9
10
   10/21/10-title 2
09
   09/17/10-title 8
08
   08/21/10-title 1
   08/06/10-title 3
07
   07/06/10-title 6
06
   06/07/10-title 5
05
   05/12/10-title 7
03
   03/16/10-title 4
01
   01/17/10-title 0

答案 1 :(得分:0)

# posts_controller
@months = @posts.group_by { |post| post.published_at.strftime("%B %Y")}

# archive view
.archive
  - @months.each do |month, posts|
    %h2= month
    %ol
      = render posts