Creating monthly archives in Rails
Written by Robin Fisher in 318 words
28
Feb
Whilst creating my own blog software has made me realise how little I needed compared to the vast functionality of readily-available software, one of the things I did want was a monthly archive view.
The first thing I did was create a method in the Entry model that would assign each entry an “archive link” consisting of the month and year in which the entry was created:
class Entry < ActiveRecord::Base
after_create :create_archive_link
...
def create_archive_link
month = self.created_at.strftime("%B %Y")
month = month.downcase.sub(/[ ]/, "")
self.month_year = month
self.save
end
I have to confess at this point that I broke from the RESTful conventions that I try to employ and created a monthly_index method in the entries controller:
def monthly_index @entries = Entry.find_all_by_month_year(params[:month]) @entry = @entries[1] @all_entries = Entry.find(:all) end
For the blog index, I then list the monthly archives using the following code:
<ul>
<% @all_entries.group_by(&:month_year).each do |month, entries| %>
<li><%= link_to "#{month} (#{entries.size})", monthly_archive_url(month.downcase.sub(/[ ]/, "")) %></li>
<% end %>
</ul>
This code does several things in a short space of time:
1) Groups each entry by a defined month_year method resulting in a hash keyed on the month_year method
2) Prepares to iterate through the hash based on the month_year key
3) Lists the month name and the number of posts in that month with a link to a monthly_archive_url route that is defined in routes.rb
In routes.rb, the following route is defined:
ActionController::Routing::Routes.draw do |map| ... map.monthly_archive 'entries/archive/:month', :controller => 'entries', :action => 'monthly_index' ... end
I think the code could be cleaned up a little bit by defining more methods in the model. Just writing this has made me think that I should define a method to convert the archive link of february2008 back into February 2008.
What I have found is that writing a lot of the code needed to run an effective blogging platform is not particularly complicated when the function needed is broken down into a series of steps.