I have models that looks like
search.rb:
id eg: 101
name eg: San Francisco
cars.rb
id
name
The search controller redirects user to cars.
search_controller.rb
if search.search_type=='cars'
redirect_to :controller=>'cars', :action=>'index', :id=>search
end
A query to find list of cars from San Francisco looks like:
http://localhost/cars?id=101
I overrode to_param method in search.rb like:
search.rb
def to_param
normalized_name = name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '')
"#{self.id}-#{normalized_name}"
end
This works to开发者_JAVA技巧 some extent: It generates URLs that look like:
http://localhost/cars?id=101-San-Francisco
However, I would like is to generate a URL that looks like
http://localhost/cars/San-Francisco
How would I go about doing that? Do I fix the routes?
Thanks for your help.
This can be tricky if you're not prepared for it. The method that controls how a model shows up in the params is pretty straightforward, as you've identified, but that's only the half of it. Later you'll have to retrieve it, so you need to set up for that:
class Search < ActiveRecord::Base
before_save :assign_slug
def self.from_param(id)
self.find_by_slug(id)
end
def to_param
self.slug
end
protected
def assign_slug
self.slug = self.name.gsub(' ', '-').gsub(/[^\w\-\.]/, '')
end
end
This requires adding a slug
column to your Search model in order to make it possible to look up a search by it. It may be a good idea to add an index, possibly a unique one, to help retrieve these later in an efficient manner.
In your controller you don't use find
but from_param
instead to do the retrieval.
You'll also need to add a custom route that takes this parameter:
match '/cars/:search', :to => 'cars#index', :as => 'cars_search'
As a note you should use the route path generator methods whenever possible because multiple routes may match the same parameters. For instance:
redirect_to cars_search_path(:search => search)
精彩评论