我将回到几个月前写的一个应用程序,并尝试进行一些小的调整。我目前有一个模型Product
和一个目录页面,其中所有产品都使用each
循环列出Product
中的所有条目。
为了确保网站安全,我已将http://.../products/...
置于身份验证登录之后,因此只有拥有密码的用户才能看到/products/index
,编辑产品详细信息并查看产品一个时间(显示页面)。
我现在想要从列出的所有产品页面链接到只有一个产品详细信息的页面(即单个产品的页面)。
我知道我可以使用Product
的查找功能找到Product ID
模型中的产品,但是,如何自动为此商品的商家信息创建合理的网址?< / p>
总之,如果我在一个页面上列出了10个产品,那么让用户点击产品并将其路由到名为http://..../shop/specific_products_name
的页面的最佳方法是什么?我已经阅读了一下,似乎to_param
可能有一些好处,但我正在努力找出一种合理的方法来创建这些页面
感谢您的时间
答案 0 :(得分:1)
这是一个基本的传统控制器设置:
首先,这是路由快捷方式语法:
# config/routes.rb
...
resources :products
...
这是控制器,可以加载index
上的所有产品,只加载show
上的一个产品。
# app/controllers/products_controller.rb
class ProductsController
def index
@products = Product.all
end
def show
@product = Product.find(params[:id])
end
end
路线文件中的那一行为我们提供了这些路线(其中包括):
/products
转到products_controller#index
/products/:id
转到products_controller#show
,并将params [:id]设置为给定的数字在您查看时,以最少的工作量获取漂亮网址的最简单方法是覆盖to_param
。
to_param
是Rails用于将模型转换为url / request中的表示的内容。
默认情况下,就是这样:
class Product
def to_param
self.id
end
end
因此,当Rails对to_param
的结果执行Product.find()时,find()
会将其转换为to_i
的整数。
如果params[:id]
为"24"
,则Product.find(params[:id])
会将“24”转换为整数24。
但请考虑to_i
如何与其他示例一起使用:
"100".to_i #=> 100
"100-flux-capacitor-2000".to_i #=> 100
换句话说,如果我们的产品参数表示为"#{id}-the-product-name"
,即使我们的产品#显示的网址看起来像Product.find(params[:id])
,/products/56-ford-taurus
仍然有用。
还有一件事:
"I love the Ford Taurus".parameterize #=> "i-love-the-ford-taurus"
解决问题的最简单方法是覆盖to_param,如下所示:
class Product
def to_param
"#{id}-#{name.parameterize}"
end
end
此方法的好处是您可以在Product模型中更改一个方法,并在代码的其余部分中更改Just Works。
缺点是您的网址如下:
/products/56-ford-taurus
而不是:
/products/ford-taurus
如果您想要后一个示例,可以在Products表中维护slug
列。
示例:
Product
id: 58
name: Ford Taurus
slug: ford-taurus
然后你可以像这样覆盖to_param:
class Product
def to_param
slug
end
end
现在,params [:id]看起来像“ford-taurus”。
由于find()想要一个整数, Product.find("ford-taurus")
将不再有效,因此您可以将Product.find(params[:id])
替换为Product.find_by_slug(params[:id])
。
你必须确保每件产品都有一个独特的slu ..
您可以通过以下方式自动化段塞创建过程:
class Product
before_create :make_slug
private
def make_slug
self.slug = name.parameterize
end
end
这样,你只需要在创建时设置产品的名称,保存它,它的slug将成为URL友好的“无论产品名称是什么”。
现在Rails将生成您想要的URL类型,您可以在以下视图中生成指向这些产品的链接:
# This would be in views/index.html.erb
<% @products.each do |product| %>
<%= link_to product.name, product %>
<% end %>
为每种产品提供此类html:
<a href="/products/56-ford-taurus">Ford Taurus</a> (if you used Solution A)
<a href="/products/ford-taurus">Ford Taurus</a> (if you used Solution B)