I am looking to do something similar a wordpress slug where I have a URL like this while maintaining RESTful routing:
http://foo.com/blog/2009/12/04/article-title
The reason I am interested in keep RESTFUL routing is that I am unable to use many plugins because I am using custom routes.
I have already done the RESTful appearance with:
map.connect '/blog/:year/:mon/:day/:slug',
:controller => 'posts', :action => 'show',
:year => /\d{4}/, :month => /\d{2}/,
:day => /\d{2}/, :slug => /.+/,
:requirements => { :year => /\d{4}/, :month => /\d{2}/, :day => /\d{2}/, :slug => /.+/ }
In order to write the links, I had to write custom link_to helpers to generate the proper URLs. I really would like to make this RESTful and have the link_to post_path( @post ) yield the URL above and the link_to edit_post_path(@post) ...article-title/edit
I also have :has_many => [:comments] and I would that to work as well. The link_to that I have tried looks like this:
'posts', :action => 'show', :year => recent_post.datetime.year.to_s,
:month => sprintf('%.2d', recent_post.datetime.mon.to_i),
:day => sprintf('%.2d', recent_post.datetime.mday.to_i),
:slug => recent_post.slug %>
and yields this (which isn't what I want):
http://foo.com/posts/show?day=30&month=11&slug=welcome-to-support-skydivers&year=2009
I'm not sure what I am doing wrong. Is it even possible to accomplish this?
I think it's not working because you're not using a custom route. I do this all of the time. I simply setup a simple custom route:
map.present_page '/blog/:year/:month/:day/:slug',
:controller => 'posts', :action => 'show'
Then you should be able to do:
present_page_path(:year => 2009,
:month => "December",
:day => "13",
:slug => "just-an-example")
The reason you're getting a query string is most likely because rails isn't making the connection to your route for whatever reason. Using a named route explicitly tells rails to use that route. Let me know if that solves it for you!
Here's how I went about this...
First, I'm not trying to use the route-generated url method. Also, I'm not going to the same extent as you in terms of checking formatting of the date parameters. Since I'm auto-generating the datestamps and the URL creation, I'm not concerned about format validity, I'm simply formatting a ActiveSupport::TimeWithZone object.
Let's start with the relevant route:
map.post_by_date 'content/:year/:month/:day/:slug',
:controller => 'posts',
:action => 'show_by_date_slug'
Since I didn't want to worry about argument formatting, or repetition, I created a helper method and included the helper in the relevant controller:
def pubdate_slug_url(post)
year = post.published_on.strftime('%Y')
month = post.published_on.strftime('%m')
day = post.published_on.strftime('%d')
url = "/" + ["content", year, month, day, post.slug].join("/")
return url
end
Finally, in my view, I simply call the method, passing in my Post object:
<h2><%= link_to post.headline, pubdate_slug_url(post) %></h2>
I end up with a url like: http://wallscorp.us/content/2009/12/06/links
Cheers.