在做 model 的 CRUD 時(shí),一個(gè)resources :events這樣的路由,它的 show 頁面的網(wǎng)址總是這樣:
/events/123
這樣的網(wǎng)址有幾個(gè)缺點(diǎn):
SEO(Search Engine Optimization、搜尋引擎優(yōu)化) 不夠好。只有數(shù)字,而不是有意義的文字。
洩露了數(shù)據(jù)庫中的資料量,聰明的用戶可以透過修改網(wǎng)址,就可以猜到數(shù)據(jù)庫有多少筆資料。
讓我們依序解決這個(gè)問題,這里提供三種層次的解決方案:
方案一:網(wǎng)址上除了數(shù)字ID,可以再加上文字
方案二:不要用數(shù)據(jù)庫的遞增數(shù)字ID,而是用一個(gè)亂數(shù)產(chǎn)生的 ID
方案三:除了用亂數(shù)ID,也可以讓用戶自定義 ID
今天學(xué)到的就是如何自定義網(wǎng)址
2-2 方案一:網(wǎng)址ID+文字
方案一:網(wǎng)址上除了數(shù)字ID,可以再加上文字

修改app/models/event.rb,加上一個(gè)to_param方法:
app/models/event.rb
class Event < ApplicationRecord? ??
validates_presence_of :name+? def to_param
+? ? "#{self.id}-#{self.name}"
+? endend
這樣就好了,出來的網(wǎng)址就會(huì)變成/events/123-活動(dòng)名稱。
解說一:
在調(diào)用路由方法時(shí),Rails 默認(rèn)都會(huì)用 to_param 方法來轉(zhuǎn)換 ID,例如:
event_path(@event)等同于event_path(@event.to_param)
而這個(gè)to_param方法其實(shí)是一個(gè) Rails 默認(rèn)就有的方法,它本來是這樣的:
def to_param
self.id
end
這就是為什么你不需要特地寫event_path(@event.id),因?yàn)?Rails 默認(rèn)調(diào)用了to_param
解說二:
在 controller 中的@event = Event.find(params[:id])為什么不需要修改呢?
因?yàn)?Rails 在find的時(shí)候,會(huì)先調(diào)用to_i轉(zhuǎn)成純數(shù)字的 ID。
而任意字串to_i之后,只會(huì)留下前面的數(shù)字,后面非數(shù)字的字串都會(huì)忽略掉。
于是"123-XXXXX".to_i就變成123了,和本來的數(shù)字ID是一致的。
2-3 方案二: 亂數(shù) ID
方案二:不要用數(shù)據(jù)庫的遞增數(shù)字ID,而是用一個(gè)亂數(shù)產(chǎn)生的 ID

如果不要顯示數(shù)據(jù)庫的遞增整數(shù) ID 的話,我們需要在 events 上新增另一個(gè)字段來做識(shí)別。
執(zhí)行 rails g migration add_friendly_id_to_events
end