通过ruby制作漂亮的url

好的,我希望事件的标题在URL中

/events/party-at-mikes 

所以这就是我的表现

 Event.find_by_title(params[:title]) 

我的链接

  <%= link_to('EVENTS', course_event_path(obj.golf_course.city.permalink, obj.golf_course.permalink, obj.title), :class => 'right eve_bnt') %> 

obj.title就是这个事件

问题是url看起来像这样

 events/Party at mikes 

我需要做的是把空间放在空间和找到捕获的地方

Andres建议重写to_param以使用title,但这是不可接受的,因为你不需要空格等。你需要的是模型的固定链接或slug,存储在下面示例中名为’slug’的字符串字段中。 这是在保存记录时创建的,随后永远不会更改:这用作url中id的替换。 slug只有字母,数字和连字符,并且可以通过在末尾添加数字来强制它们是唯一的。 然后,你改变to_param来使用slug,你可以在你的控制器中找到slug。 例如

 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 

在你的事件控制器中

  before_filter :load_event, :except => [:index, :new] ... protected def load_event @event = Event.find_by_slug(params[:id]) end 

你应该看看friendly_id gem。 它的目的是完全符合你的意图,并处理许多边缘情况。 让这有点痛苦的主要边缘情况是:如果两个事件具有完全相同的标题怎么办?

忽略极端情况,正确的方法是重载您的类的两个方法:

 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 

请访问http://railscasts.com/episodes/63-model-name-in-url

我肯定会在url中保留id以及附加友好名称的路线。 如果你有一个糟糕的记录,这使得调试更容易,并且实现起来很简单。 更不用说sql可以找到比varchar快得多的int。

只需将其放入模型中即可。 无需定义段塞方法,因为这已经通过参数化在轨道中提供。 它还具有需要对其他代码进行0更改的优点。 这几乎适用于所有开箱即用的情况。

 # Slug the url. def to_param "#{id}-#{title.parameterize}" end