2010-09-19 55 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