假设我有一个相对基本的CRUD应用程序来编辑音乐专辑。在数据库中我有:
id | album_name | artist | navigation
1 Lets Talk Lagwagon lets-talk
但是,我希望页面可以albums/1
路径访问,而不是Show
返回albums/lets-talk
页面。
所以在我的控制器里我有:
def show
@album = Album.find_by_navigation(params[:id])
end
在我的索引视图中,我有:
<%= link_to 'Show', :controller => "albums", :action => "show", :id => album.navigation %>
这成功地执行了它的功能,但是,Ruby API说我的link_to方法陈旧且陈旧而没有列出替代方案,所以我怀疑我的方法是错误的。
答案 0 :(得分:17)
在模型中定义你的to_param:
class album
def to_param
"#{id}-#{album-name.parameterize}"
end
end
现在你可以使用
<%= link_to album.album_name, album %>
创建指向seo路径的链接
然后在你的控制器中:
Album.find(params[:id])
将致电to_i
- &gt;所以你得到Topic.find(2133)
或其他什么。
这将导致以下形式的网址:“/ album / 2-dark-side-of-the-moon”尽管不是所要求的具有优势 - 该ID用于查找相册 - 这是唯一的,当名称可能不是。
参数化方法“替换字符串中的特殊字符,以便它可以用作'漂亮'网址的一部分” - http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize
答案 1 :(得分:5)
查看friendly_id gem。这正是你所需要的。
答案 2 :(得分:1)
如果您希望在浏览器中将app/albums/lets-talk
显示为URL,而将POST参数显示为album_id => 1
,则添加购物车等
在您的相册模型中:
# PRODUCT MODEL
before_create do
self.navigation = album_name.downcase.gsub(" ", "-")
end
def to_param
[id, album_name.parameterize].join("-")
end
现在你可以
@album = Album.find_by_navigation(params[:id])
和
album = Album.find(params[:album_id])
答案 3 :(得分:0)
好像你想要覆盖:id参数:name参数。 this article中描述了这种情况。
class User < ActiveRecord::Base
def to_param # overridden
name
end
end
user = User.find_by_name('Phusion')
link_to 'Show', user_path(user) # => <a href="/users/Phusion">Show</a>