Reputation: 617
I have a blog function in my rails app. Currently I only have 4 bloggers on the site and have a (pretty unsatisfied) way of routing them like this:
map.scarlet '/scarlet.:format', :controller => 'blogs', :action => 'show', :id => 'scarlet'
map.alba '/andreasweinas.:format', :controller => 'blogs', :action => 'show', :id => 'alba'
So that they are nicely accessible by typing: mysuperwebsite.com/scarlet
Now I would like to provide archives for the blogs accessible like so:
mysuperwebsite.com/scarlet/2009 - shows all entries from 2009
mysuperwebsite.com/scarlet/2009/06 - shows all entries from june 2009
Would anyone recommend how to a) improve my blog routing having in mind that in the future I'll have far more bloggers, and b) how to route for the archives without breaking the paths? I'm thinking an archives controller?
Models:
# Blog.rb
class Blog < ActiveRecord::Base
has_many :entries, :dependent => :destroy
belongs_to :user
end
class Entry < ActiveRecord::Base
named_scope :published, :conditions => ["published_at < ?", Time.zone.now], :order => 'published_at DESC'
belongs_to :blog
end
Blog Controller:
def show
@blog = Blog.find_by_slug(params[:id])
@entries = @blog.entries.published, :order => 'published_at DESC'
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @blog.entries }
format.rss
end
end
Upvotes: 1
Views: 264
Reputation: 31
This is untested, but should be very close. Not the DRYest solution, but you can refactor it. This will make the date filter work AND allow you have new blogs and support the existing routes. Enjoy
routes.rb
#(you don't need the .format) bit
# (if you have other routes, like /help, you need to have them before these, since these match /*, /\*/\*, and /\*/\*/\*
map.blogs '/:id/:year/:month', :controller => 'blogs', :action => 'show'
map.blogs '/:id/:year', :controller => 'blogs', :action => 'show'
map.blogs '/:id.:format', :controller => 'blogs', :action => 'show'
Blogs controller:
def show
@blog = Blog.find_by_slug(params[:id])
if (params[:year])
if (!params[:month])
date_begin = Date.new(params[:year],1,1)
date_end = Date.new(params[:year],12,31)
date_end = Time.zone.now if date_end < Time.zone.now # to prevent grabbing future posts
@entries = Entries.find(:conditions => [blog => @blog, :published_at => date_begin..date_end ],
:order => 'published_at DESC'
else
date_begin = Date.new(params[:year],params[:month],1)
date_end = date_being.end_of_month
date_end = Time.zone.now if date_end < Time.zone.now # to prevent grabbing future posts
@entries = Entries.find(:conditions => [blog => @blog, :published_at => date_begin..date_end ],
:order => 'published_at DESC'
end
else
@blog.entries.published, :order => 'published_at DESC'
end
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @entries } # I changed this too
format.rss
end
end
Upvotes: 1