Let''s say you''re building a movie rental website. You have customers, movies, and rentals to manage. REST style urls might look like this: /customers/4 /movies/15 /rentals You''d probably also want administrators to be able to view all of the rentals done by a particular customer, and other similar details: /customers/4/rentals /movies/15/rentals /rentals/529/customers Except you can''t, at least not as far as I understand route generation. Looking at routes.rb for the example: map.resources :movies do |movies| movies.resources :rentals end map.resources :rentals do | rentals| rentals.resources :customers end map.resources :customers do |customers| customers.resources :rentals end These map blocks introduce ambiguity about what rental_url(1,5) should generate - /movies/1/rentals/5 or /customers/1/movies/5. The error message pointing this out sucks (rentals_url failed to generate from {:controller=>"rentals", :action=>"index"}, expected: {:controller=>"rentals", :action=>"index"}, diff: {}), but I digress. Instead of throwing an error in this kind of situation (which I imagine would be relatively common), why not take a named route like customer_rentals_url(1,5) or new_movie_rental_url(1) when there is ambiguity? There may be a very good reason why not, and I''m new here, so bear with me. :) -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2006-Dec-17 18:21 UTC
Re: Route generation and clash prevention
Hi -- On Sun, 17 Dec 2006, D. Scott Brown wrote:> > Let''s say you''re building a movie rental website. You have customers, > movies, and rentals to manage. REST style urls might look like this: > > /customers/4 > /movies/15 > /rentals > > You''d probably also want administrators to be able to view all of the > rentals done by a particular customer, and other similar details: > > /customers/4/rentals > /movies/15/rentals > /rentals/529/customers > > Except you can''t, at least not as far as I understand route generation. > Looking at routes.rb for the example: > > map.resources :movies do |movies| > movies.resources :rentals > end > > map.resources :rentals do | rentals| > rentals.resources :customers > end > > map.resources :customers do |customers| > customers.resources :rentals > endDo you really want both rentals/customers and customers/rentals?> These map blocks introduce ambiguity about what rental_url(1,5) should > generate - /movies/1/rentals/5 or /customers/1/movies/5. The error > message pointing this out sucks (rentals_url failed to generate from > {:controller=>"rentals", :action=>"index"}, expected: > {:controller=>"rentals", :action=>"index"}, diff: {}), but I digress.Yes, that error message is a source of much frustration as well as amusement :-)> Instead of throwing an error in this kind of situation (which I imagine > would be relatively common), why not take a named route like > customer_rentals_url(1,5) or new_movie_rental_url(1) when there is > ambiguity? > > There may be a very good reason why not, and I''m new here, so bear with > me. :)I''m a little uncertain what you want the end result to be (a couple of things in the examples aren''t clear to me), but it sounds like you could make use of name prefixes -- for example: map.resources :rentals do |rentals| rentals.resources :movies, :name_prefix => "movies_" rentals.resources :customers, :name_prefix => "customers_" end which (if I''ve got [untested] syntax right) should give you rentals_movies_url, rentals_customers_url, and so forth. To do it the other way around, you would do: map.resources :movies do |movies| movies.resources :rentals, :name_prefix => "movies_" end and the same for :customers, to get movies_rentals and customers_rentals. David -- Q. What''s a good holiday present for the serious Rails developer? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) aka The Ruby book for Rails developers! Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> I''m a little uncertain what you want the end result to be (a couple of > things in the examples aren''t clear to me), but it sounds like you > could make use of name prefixes -- for example: > > map.resources :rentals do |rentals| > rentals.resources :movies, :name_prefix => "movies_" > rentals.resources :customers, :name_prefix => "customers_" > end > > which (if I''ve got [untested] syntax right) should give you > rentals_movies_url, rentals_customers_url, and so forth. To do it the > other way around, you would do: > > map.resources :movies do |movies| > movies.resources :rentals, :name_prefix => "movies_" > end > > and the same for :customers, to get movies_rentals and > customers_rentals.Eureka, that did the trick! Thanks David, you rock. The only catch is that the prefix is truly a prefix - you must do movie_new_rental_path instead of the catchier new_movie_rental_path. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---