A bout Search engine friendly URL

Hi All,

Can anyone talk about how to generate url like : http://blogs.tech-recipes.com/johnny/2006/08/27/ruby-on-rails-using-full-text-search-with-tagging

Is the title string "ruby-on-rails-using-full-text-search-with- tagging" set as the primary key or...

if then how to handle the case that in a same day, we hv two articles with exactly the same title string.

Thanks in advance.

This is done by using a custom named route, as designated in your config/routes.rb file.

A good way of explaining how this particular example (http://blogs.tech-recipes.com/johnny/2006/08/27/ruby-on-rails-using-full-text-search-with-tagging) may have been formed using Rails, would be this (a possible line in the routes.rb file):

   map.post ':user/:year/:month/:day/:title', :controller => 'posts', :action => 'show'

This will route any request that matches that format (i.e. /johnny/2006/08/27/ruby-on-rails-blah-blah) to the 'show' action under your 'posts' controller. The values you specify as each 'segment' of the uri (in this example, you are using 'johnny' under the :user and 2006 as the :year), will be passed to your controller under the 'params' hash, allowing you to access them from within the controller. An example in your controller would be:

   @post = Post.find(:first, :conditions => [:author => params[:user], :subject => params[:title]])

[If anything I'm typing is wrong, please let me know everyone]. As you can guess, this would allow you to pass the values in the (nicely formed) URL to your controller, and work with it as you like.

In response to your second question; no, the title would not be the primary key here. The primary key is actually not included in the URL at all (unless you form a composite primary key, which would only seem sensible to use all the segments together, but that's probably not very efficient), and you would have to write a find statement to search your database for the first post that matches your input -- because of this, you run the risk of having two posts named exactly the same posted on the same day, but only one would be found. If this is the case, then a URL format like this obviously would not suffice. You would have to add your own identifier on the end, perhaps:

   map.post ':user/:year/:month/:day/:title/:iterator', :controller => 'posts', :action => 'show', :iterator => 1

(Note that the default value for your :iterator parameter can be set in the routes file too, so if it is not set in the URL, it will default to 1. You can also add validation on your params here, but that is for a later e-mail =P).

This was, you can tell your 'find' statement to skip a certain number of posts (from the same day, with the same name) in order to find the one you want.

I hope this helps and I'm not completely missing the point of your question. Also, if any rails ninjas superior to me spot any inefficiencies or mistakes please call me out on it.

there's a number of plugins to do this:

http://agilewebdevelopment.com/plugins/search?search=url+slug

The basic idea is just to override the to_param method for the id of the model object being referenced. If to_param returns a number followed by a hyphen and a string, then that is what will be displayed when a URL is generated that references that ID. And when the ID is passed to a find method, it is automatically converted to an integer, which strips the string and leaves just the numeric ID. The various plugins that are available just simplify this by providing processing for the string field to make it safe to use in a URL (for example, by replacing spaces with hyphens).

Michael www.buildingwebapps.com

Thanks for all your replies.