Ok so i want the title of an event to be in the url like
/events/party-at-mikes
so here is how i am doing it
Event.find_by_title(params[:title])
my link
<%= link_to('<span>EVENTS</span>', course_event_path(obj.golf_course.city.permalink, obj.golf_course.permalink, obj.title), :class => 'right eve_bnt') %>
the obj.title is the event
the problem is t开发者_如何学Chat the url looks like this
events/Party at mikes
what do i need to do to make is put the - in space of spaces and on the find capture that
You should really look at the friendly_id gem. It purports to do exactly what you're intending, and takes care of a number of edge cases. The main edge case that makes this a bit of a pain is: what if two events have the exact same title?
Ignoring the corner cases, the correct way to do this is to overload two methods of your class:
class Event < ActiveRecord::Base
...
# This is used automatically to build the :id component of the url
# in the form /models/:id
def to_param
self.title
end
# Now assuming that you just use Event.find(params[:id]),
# you probably want Event.find to work differently.
def self.find(identifier)
self.find_by_title(identifier)
end
...
end
Andres suggests overriding to_param to use title, but this isn't acceptable as you don't want spaces etc. What you need is a permalink, or slug, for the model, stored in a string field called 'slug' in the example below. This gets created when the record is saved, and subsequently never changes: this is used as the replacement for id in urls. The slug has only letters, numbers and hyphens, and can be forced to be unique by the addition of numbers to the end. Then, you change to_param to use the slug, and you find by slug in your controller. eg
before_create :set_slug
def set_slug
slug = self.title.downcase.gsub(/[^a-z0-9]/,"-")
suffix = ""
while self.class.find_by_slug(slug)
slug.gsub!(/#{suffix}$/,(suffix == "" ? 1 : suffix+=1).to_s)
end
self.slug = slug
end
def to_param
self.slug
end
In your events controller
before_filter :load_event, :except => [:index, :new]
...
protected
def load_event
@event = Event.find_by_slug(params[:id])
end
Have a look at http://railscasts.com/episodes/63-model-name-in-url
I would definitely go the route of keeping the id in the url along with a friendly name attached to it. This makes debugging easier if you have a bad record, and is trivial to implement. Not to mention sql can find an int far faster than a varchar.
Just drop this in your model. No need to define the slugging method, since this is provided in rails already via parameterize. It also has the advantage of requiring 0 changes to your other code. This will work in almost all situations out of the box.
# Slug the url.
def to_param
"#{id}-#{title.parameterize}"
end
精彩评论