#70
Sep 10, 2007

Custom Routes

In this episode you will learn how to add custom routes, make some parameters optional, and add requirements for other parameters.
Download (10.6 MB, 7:05)
alternative download for iPod & Apple TV (8.5 MB, 7:05)

Resources

# in routes.rb
  map.connect 'articles/:year/:month/:day', :controller => 'articles',
    :month => nil, :day => nil, :requirements => { :year => /\d{4}/ }

RSS Feed for Episode Comments 18 comments

1. Ekolguy Sep 10, 2007 at 00:13

Thanks for this one Ryan!

It would be nice to see the code for by_date method too though.

Also what happens if the id of the article has 4 characters in it? Any other method of escaping from this?

Cheers.


2. Omar Sep 10, 2007 at 04:24

@ekolguy

I guess it shouldnt matter because what the route is aiming to do is to stop the show action being interpreted as a date (for the index action)


3. Ted Sep 10, 2007 at 05:04

I'm telling Jack you were working on a new episode while he was slaving over your Rails Rumble project ;-)


4. nicolash Sep 10, 2007 at 05:09

Thanks for your screencasts.

Maybe you should consider a Tag "routing" for these editions...

070_custom_routes
046_catch_all_route
035_custom_rest_actions
034_named_routes


5. Ryan Bates Sep 10, 2007 at 08:09

@Ekolguy, I would but the by_date method is such an ugly hack that I don't want to show it. Maybe I'll improve it and turn it into an episode some day.

Regarding the routing, The name of the action shows up in the URL so there's no conflict. If I were using restful routes where the article ID showed up where the year goes, then I would have a problem. In that case I'd probably make a new route for the show action to include the date in that too.

@Ted, LOL. Actually I whipped this up right after the event last night. That's why I sound tired.

@nicolash, good idea! I'll add that. Thanks for the suggestion!


6. Ryan Sep 11, 2007 at 14:07

Have any thoughts about how (and more importantly, when) to use method_missing in any of your upcoming screencasts? I guess maybe just a little metaprogramming in general might be nice, since that's an important thing to understand in Ruby. Just a thought...


7. Dibi Store Sep 11, 2007 at 14:27

thank you


8. Kelli Sep 16, 2007 at 23:04

Ryan, that was incredibly useful, thanks. I never would have thought of it, but it makes perfect sense upon seeing it. You don't sound nearly as tired as I felt!


9. Jose Oct 12, 2007 at 01:46

Hy Ryan,
please how can we do a link to an article like /articles/2007/10/12/id_of_article

Thanks a lot.


10. Ryan Bates Oct 12, 2007 at 08:16

@Jose, you can do a link by passing the parameters like this:

link_to "Article", :controller => 'articles', :year => 2007, :month => 10, :day => 12


11. Jose Oct 12, 2007 at 10:52

Thanks Ryan for your answer, but I have a problem, if I do:

link_to 'article', :controller => "articles", :year => '2007', :month => '10')

I get:

http://localhost:3000/articles?year=2007&month=10

Not:

http://localhost:3000/articles/2007/
10

And my route file is:

  map.connect 'articles/:year/:month', :controller => 'articles',
    :year => nil, :month => nil

Is this correct?


12. Ryan Bates Oct 12, 2007 at 15:00

@Jose, hmm, it should work as long as that route is near the top of your routes.rb file. But, I haven't tested this very much, I usually use named routes. Here's an example of that:

http://pastie.caboo.se/106752

I explain named routes more in this episode:

http://railscasts.com/episodes/34


13. Dom Jan 02, 2008 at 21:26

For those looking for Ryan's ugly hack for the by_date method check it out here:

http://railsforum.com/viewtopic.php?id=3741

I found this today and it presented a clever way to accomplish this functionality. It may not be pretty or rails-ish Ryan, but it gets the job done!

Thanks for all the casts Ryan - I check here when I don't know something, before I check anyway else. I subscribed today to your feed in iTunes, so I'll make sure I get the votes going.


14. nelson Apr 03, 2008 at 10:02

Ryan Bates, Hi. :)

Man, I have one problem. :\
look: http://pastie.caboo.se/174710

How are your code by_date?

[]s
tks.


15. David May 19, 2008 at 15:15

thank you


16. kino May 23, 2008 at 01:54

Because of our necessary ignorance of the conditions, let us suppose that the Antinomies stand in need to space; with the sole exception of the thing in itself, our judgements can never, as a whole, furnish a true and demonstrated science, because, like the Ideal of human reason, they prove the validity of a posteriori principles.


17. IMA Oct 14, 2008 at 04:57

Thank you form that nice Screencast - exactly what I was looking for :-)


18. Austin Schneider Nov 17, 2008 at 09:40

For all who are interested, this is what I did:

In the controller:

def find_by_date
  @posts = blog.posts.by_year(params[:year])
  if params[:month]
    @posts = @posts.by_month(params[:month])
    @posts = @posts.by_day(params[:day]) if params[:day]
  end
end

=================

In the model:

named_scope :by_year, lambda { |year| {:conditions => ["YEAR(created_at) = ?", year]} }
named_scope :by_month, lambda { |month| {:conditions => ["MONTH(created_at) = ?", month]} }
named_scope :by_day, lambda { |day| {:conditions => ["DAY(created_at) = ?", day]} }

=================

I'd like to move more of the code into the model, I just haven't thought of a good way yet.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player