2009-07-03 11 views
5

Hola chicos. Creé una aplicación de blog simple con las acciones habituales de CRUD. También agregué una nueva acción en el PostController llamada "archivo" y una vista asociada. En este punto de vista quiero traer de vuelta todos los blogs y agruparlos por mes, mostrándolos en este tipo de formato:Ruby on Rails: agrupar publicaciones en el blog por mes

March 
<ul> 
    <li>Hello World</li> 
    <li>Blah blah</li> 
    <li>Nothing to see here</li> 
    <li>Test post...</li> 
</ul> 

Febuary 
<ul> 
    <li>My hangover sucks</li> 
    ... etc ... 

no puedo por la vida de mí averiguar la mejor manera de hacer esto. Suponiendo que el modelo de publicación tenga los campos usuales title, content, created_at etc., ¿alguien puede ayudarme con la lógica/código? Estoy muy nuevo en RoR así que por favor tengan paciencia conmigo :)

Respuesta

31

group_by es un gran método:

controlador:

def archive 
    #this will return a hash in which the month names are the keys, 
    #and the values are arrays of the posts belonging to such months 
    #something like: 
    #{ "February" => [#<Post 0xb5c836a0>,#<Post 0xb5443a0>], 
    # 'March' => [#<Post 0x43443a0>] } 
    @posts_by_month = Posts.find(:all).group_by { |post| post.created_at.strftime("%B") } 
end 

vista de plantilla:

<% @posts_by_month.each do |monthname, posts| %> 
<%= monthname %> 
<ul> 
    <% posts.each do |post| %> 
    <li><%= post.title %></li> 
    <% end %> 
</ul> 
<% end %> 
+3

Esto está más relacionado con el OP: * Es posible que desee agrupar por Año-Mes, porque una vez que pase al año siguiente (por ejemplo, 2010), la sección de enero tendrá las entradas de 2009 y 2010. * Es posible que desee tener las entradas de cada mes ordenadas por fecha (día), para asegurarse de que la lista sea cronológica. – BryanH

+2

¡Solución perfecta! Muchas gracias :) –

+0

Palm slap moment, he estado haciendo mi propia funcionalidad group_by para mostrar grupos de registros en mis vistas. Me alegro de haber descubierto esto. –

7

@Maximiliano Guzmán

¡Buena respuesta! Gracias por agregar valor a la comunidad de Rails. Incluyo mi fuente original en How to Create a Blog Archive with Rails, solo en caso de que anule el razonamiento del autor. Basado en la publicación del blog, para nuevos desarrolladores de Rails, agregaría un par de sugerencias.

En primer lugar, use Active Records Posts.all método para devolver el conjunto de resultados de publicación para aumentar la velocidad y la interoperabilidad. Se sabe que el método Posts.find (: all) tiene problemas imprevistos.

Finalmente, en la misma línea, use beginning_of_month método de las extensiones del núcleo de ActiveRecord. Encuentro beginning_of_month mucho más legible que strftime ("% B"). Por supuesto, la elección es tuya.

A continuación se muestra un ejemplo de estas sugerencias. Por favor, vea la entrada del blog original para más detalle:

controladores/archives_controller.rb

def index 
    @posts = Post.all(:select => "title, id, posted_at", :order => "posted_at DESC") 
    @post_months = @posts.group_by { |t| t.posted_at.beginning_of_month } 
end 

views/archivos/indext.html.erb

<div class="archives"> 
    <h2>Blog Archive</h2> 

    <% @post_months.sort.reverse.each do |month, posts| %> 
    <h3><%=h month.strftime("%B %Y") %></h3> 
    <ul> 
     <% for post in posts %> 
     <li><%=h link_to post.title, post_path(post) %></li> 
     <% end %> 
    </ul> 
    <% end %> 
</div> 

Buena suerte y bienvenido a Rails!

+0

Wahhh .. bien .. muchas gracias Steve! – Abhi

+0

@steve, ¿Qué tal eso, afecta a cualquier velocidad?si no quiero usar ** y solo uso esta línea? Post.all (: select => "title, id, posted_at",: order => "posted_at DESC") **. ** @ posts = Post.order ('created_at DESC'). Group_by {| post | post.created_at.beginning_of_month} ** – JAML