I'd like my website to have URLs looking like this:
example.com/2010/02/my-first-post
I have my Post
model with slug
field ('my-first-post') and published_on
field (from which we will deduct the year and month parts in the url).
I want my Post
model to be RESTful, so things like url_for(@post)
work like they should, ie: it should generate the aforementioned url.
Is there a way to do this? I know you need to override to_param
and have map.resources :posts
with :requirements
option set, but I cannot get it all to work.
I have it almost done, I'm 90% there. Using resource_hacks plugin I can achieve this:
map.resources :posts, :member_path => '/:year/:month/:slug',
:member_path_requirements => {:year => /[\d]{4}/, :month => /[\d]{2}/, :slug => /[a-z0-9\-]+/}
rake routes
(...)
post GET /:year/:month/:slug(.:format) {:controller=>"posts", :action=>"show"}
and in the view:
<%= link_to 'post', post_path(:slug => @post.slug, :year => '2010', :month => '02') %>
generates proper example.com/2010/02/my-first-post
link.
I would like this to work too:
<%= link_to 'post', post_path(@post) %>
But it needs overriding the to_param
method in the model. Should be fairly easy, except for the fact, that to_param
must return String
, not Hash
as I'd like it.
class Post < ActiveRecord::Base
def to_param
{:slug => 'my-first-post', :year => '2010', :month => '02'}
end
end
Results in can't convert Hash into String
error.
This seems to be ignored:
def to_param
'2010/02/my-first-post'
end
as it results in error: post_url failed to generate from {:action=>"show", :year=>#<Post id: 1, title: (...)
(it wrongly assigns @post object to the :year key). I'm kind of clueless at how to hack it.