Maxime Garcia
2012-Jul-15 20:34 UTC
RFC: MyModel#to_params for use in url helpers & url_for
Building a website with SEO considerations leads to have slugs in the urls. There is the trivial case of /products/256-my-great-product easily done changing Product#to_param. But there many others cases not as trivial. Considering the route (i use a plain match-like route instead of resourcesfor the example) : get "/products/:type_slug/:brand_slug/:token-:slug", :to => "controller#action", :as => "product" *I''d add that the id is in fact a md5-like id (NoSQL : mongodb, couchdb....), so we want naturally use a short token.* Obviously, link_to("My product", @myproduct), url_for(@myproduct) and product_path(@myproduct) fail. To generate such a route, we need to do : product_path(:type_slug => product.type_slug, :brand_slug => product.brand_slug, :token => product.token, :slug => product.slug) So here is the thing. Doing link_to("My product", @myproduct), url_for(@myproduct) and product_path(@myproduct) is nice. If we manually define : class Product def to_params { :token => token, :slug => slug, :brand_slug => brand_slug, :type_slug => type_slug } endend Then we could use product_path(@myproduct.to_params). And if the named url helpers recognize that our object respond_to? :to_params, using this #to_params-returned Hash to build the url, we could use product_path(@myproduct). For now, a named url helper is just basically replacing the dynamic url segments from left to right by its arguments from first to last, applying them a #to_param. And if the polymorphic_url recognize that our object respond_to? :to_params, passing this #to_params-returned Hash to the named url helper, we could use link_to("My product", @myproduct), url_for(@myproduct). Just enough to be nice. And SEO-friendly without pain. Waiting for comments, thoughts and anything else helpful :) Maxime. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/b38QotnRQF8J. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Scott Gonyea
2012-Jul-16 00:19 UTC
Re: RFC: MyModel#to_params for use in url helpers & url_for
Seems like this belongs in a helper. slugged_product_path(@product) Alternatively, you could simply pre-generate the slugged-URL and store it with the product itself, or in a K/V store, or etc. Generating a slugged path every single time doesn''t seem like the best use of resources. Regardless, I''m not sure this logic necessarily belongs in the Model. I''d probably create a SluggedPathsHelper module and store this logic there, and keep the Model clean. #to_params is also a terrible name for a method like this. If you did put it in the Model, you''d probably want to call it #slugged_product_path_params. It''s long, but you''ll know wtf it does 3-months from now. Scott On Jul 15, 1:34 pm, Maxime Garcia <maxime.gar...@free.fr> wrote:> Building a website with SEO considerations leads to have slugs in the urls. > > There is the trivial case of /products/256-my-great-product easily done > changing Product#to_param. But there many others cases not as trivial. > > Considering the route (i use a plain match-like route instead of resourcesfor the example) : > > get "/products/:type_slug/:brand_slug/:token-:slug", :to => "controller#action", :as => "product" > > *I''d add that the id is in fact a md5-like id (NoSQL : mongodb, > couchdb....), so we want naturally use a short token.* > > Obviously, link_to("My product", @myproduct), url_for(@myproduct) and > product_path(@myproduct) fail. > > To generate such a route, we need to do : > > product_path(:type_slug => product.type_slug, :brand_slug => product.brand_slug, :token => product.token, :slug => product.slug) > > So here is the thing. Doing link_to("My product", @myproduct), > url_for(@myproduct) and product_path(@myproduct) is nice. > > If we manually define : > > class Product > def to_params > { > :token => token, > :slug => slug, > :brand_slug => brand_slug, > :type_slug => type_slug > } > endend > > Then we could use product_path(@myproduct.to_params). > > And if the named url helpers recognize that our object respond_to? > :to_params, using this #to_params-returned Hash to build the url, we could > use product_path(@myproduct). For now, a named url helper is just basically > replacing the dynamic url segments from left to right by its arguments from > first to last, applying them a #to_param. > > And if the polymorphic_url recognize that our object respond_to? :to_params, > passing this #to_params-returned Hash to the named url helper, we could use link_to("My > product", @myproduct), url_for(@myproduct). > > Just enough to be nice. And SEO-friendly without pain. > > Waiting for comments, thoughts and anything else helpful :) > > Maxime.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.