2010-09-19 26 views
1

行,所以我希望有一个事件的标题是在URL像通过红宝石制作一个漂亮的URL

/events/party-at-mikes 

所以这里是我如何做它

Event.find_by_title(params[:title]) 

我的链接

<%= link_to('<span>EVENTS</span>', 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 

什么我需要做的,使被放 - 在空间中的空间和查找捕获的方式

回答

2

安德烈斯建议压倒一切的to_param使用标题,但是这是不可接受的,因为你不需要空格等等。你需要的是模型的永久链接或slug,存储在下面例子中的一个名为'slug'的字符串字段中。记录保存时会创建该记录,并且随后不会更改:这将用作URL的ID替换。 slu has只有字母,数字和连字符,并且可以通过在最后添加数字而被强制为唯一。然后,您更改to_param以使用slu and,并通过控制器中的slu find查找。例如

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 
4

你真的应该看看friendly_id宝石。它声称完全符合你的意图,并处理一些边缘案例。造成这种痛苦的主要原因是:如果两个事件具有完全相同的标题?

忽略的角落情况下,要做到这一点,正确的方法是重载类的方法有两种:

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 
+1

我真的不喜欢那个'friendly_id'改变调用诸如Event.id的功能的事实,它不再返回其主键,但指定的塞来代替。 否则它是相当不错的! – 2010-09-19 21:36:16

+1

我不认为它侵入'id',只是'to_param'。 – hurikhan77 2010-09-19 21:58:09

1

我肯定会去重视它一个友好的名称一起保持ID中的URL路径。这使得调试更容易,如果你有一个不好的记录,并且实现微不足道。更不用说sql可以找到一个比varchar快得多的int。

只需将其放入模型即可。不需要定义slugging方法,因为这是通过参数化在rails中提供的。它还具有对其他代码进行0更改的优点。这几乎可以在任何情况下使用。


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

还有一个证据表明只有'to_param'需要被覆盖(就像friendly_id一样)。 – hurikhan77 2010-09-23 21:51:24