Отображение ежемесячного архива постов в блоге - PullRequest
1 голос
/ 27 марта 2011

Я пытаюсь создать архивную страницу для своего блога.В нем должны быть перечислены все названия блогов, упорядоченные в хронологическом порядке в обратном порядке, сгруппированные по месяцам.

Я использую DataMapper, у которого нет функции DATE_FORMAT, как MySQL, что означает, что я не могу просто сгруппировать в запросе.Поэтому я не вижу другого способа, кроме как выполнить всю тяжелую работу в простом 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 ]

1 голос
/ 27 марта 2011
# 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
0 голосов
/ 29 марта 2011
# 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
...