Hy guys. I've created a simple blog app with the usual CRUD actions. I've also added a new action in the PostController called "archive" and an associated view. In this view I want to bring back all blog posts and group them by month, displaying them in this kind of format:
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 ...
I can't for the life of me figure out the best way to do this. Assuming the Post model has the usual title
, content
, created_at
etc fields, can someone help me out with the logic/code? I'm very new to RoR so please bear with me :)
group_by is a great method:
controller:
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
view template:
<% @posts_by_month.each do |monthname, posts| %>
<%= monthname %>
<ul>
<% posts.each do |post| %>
<li><%= post.title %></li>
<% end %>
</ul>
<% end %>
@Maximiliano Guzman
Good answer! Thanks for adding value to the Rails community. I'm including my original source on How to Create a Blog Archive with Rails, just in case I butcher the author's reasoning. Based on the blog post, for new developers to Rails, I'd add a couple suggestions.
First, use Active Records Posts.all method to return the Post result set for increased speed and interoperability. The Posts.find(:all) method is known to have unforeseen issues.
Finally, along the same vein, use beginning_of_month method from the ActiveRecord core extensions. I find beginning_of_month much more readable than strftime("%B"). Of course, the choice is yours.
Below is an example of these suggestions. Please see the original blog post for further detail:
controllers/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/archives/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>
Good luck and welcome to Rails!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With