ruby-on-rails - 用于显示操作的 URL 中的自定义参数

标签 ruby-on-rails ruby ruby-on-rails-3 routing seo

我正在努力实现 SEO 层次结构,这意味着我需要为显示操作添加参数。

用例是一个搜索站点,其中 URL 结构为:
/cars/(:brand)/ => 列表页面
/cars/(:brand)/(:model_name)?s=query_params => 搜索 Action
/cars/:brand/:model_name/:variant/:id => 车展 Action

我的问题是无需提供 :brand:model_name :variant 作为单独的参数。它们始终作为资源上的值提供。

我有: /cars/19330-Audi-A4-3.0-TDI

我想要什么 /cars/Audi/A4/3.0-TDI/19330

以前,routes.rb 是这样的:

# Before
resources :cars. only: [:show] do
  member do
  get 'favourize'
  get 'unfavourize'
end

以下是我的第一次尝试:

# First attempt
scope '/cars/:brand/:model_name/:variant' do
  match ":id" => 'cars_controller#show'
  match ":car_id/favourize" => 'cars_controller#favourize', as: :favourize_car
  match ":car_id/unfavourize" => 'cars_controller#unfavourize', as: :unfavourize_car
end

这使得可以做到:
cars_path(汽车,品牌:car.brand,型号名称:car.model_name,变体:car.variant)
但这显然不是很理想。

如何设置路由(也许还有 .to_param 方法?),而不会使更改所有 link_to 成为一项繁琐的任务电话?

提前致谢!

-- 更新--

根据@tharrisson 的建议,这是我尝试过的:

# routes.rb
match '/:brand/:model_name/:variant/:id' => 'cars#show', as: :car

# car.rb
def to_param
  # Replace all non-alphanumeric chars with - , then merge adjacent dashes into one
  "#{brand}/#{model_name}/#{variant.downcase.gsub(/[^[:alnum:]]/,'-').gsub(/-{2,}/,'-')}/#{id}"
end

该路线运行良好,例如/cars/Audi/A4/3.0-TDI/19930 显示正确的页面。但是,使用 to_param 生成链接不起作用。示例:

link_to "car link", car_path(@car)
#=> ActionView::Template::Error (No route matches {:controller=>"cars", :action=>"show", :locale=>"da", :brand=>#<Car id: 487143, (...)>})
link_to "car link 2", car_path(@car, brand: "Audi")
#=> ActionView::Template::Error (No route matches {:controller=>"cars", :action=>"show", :locale=>"da", :brand=>"Audi", :model_name=>#<Car id: 487143, (...)>})

Rails 似乎不知道如何将 to_param 转换为有效链接。

最佳答案

我看不出有什么方法可以在不调整 URL 识别或 URL 生成的情况下使用 Rails 做到这一点。

在您的第一次尝试中,您的 URL 识别工作正常,但生成失败。我可以看到使生成工作的解决方案是覆盖 car_path 辅助方法。

另一种解决方案可能是,就像您在 UPDATE 中所做的那样,覆盖 Car 的 to_param 方法。请注意,您的问题不在 to_param 方法中,而是在路由定义中:您需要提供 :brand:model_name :variant 参数,当你想生成路由时。为了解决这个问题,您可能需要使用 Wildcard segment在你的路线上。

最后你还可以使用 routing-filter gem这使您能够在 url 识别/生成之前和之后添加逻辑。

对我来说,所有这些解决方案看起来都有些繁重,并不像应该的那样简单,但我相信这是您的需要,因为您想在 URL 中添加一些级别而不严格遵循 rails 行为,这将给你像 /brands/audi/models/A3/variants/19930

这样的 URL

关于ruby-on-rails - 用于显示操作的 URL 中的自定义参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9806319/

相关文章:

ruby-on-rails - 如何删除验证?

ruby-on-rails - Rails 分页 : How to get the first element of the second page

ruby-on-rails - .on ("click",使用 ajax 呈现链接时,function() 不起作用

ruby-on-rails - Rails Controller 是多线程的吗? Thread.exclusive 在 Controller 中

ruby-on-rails - Rails SELECT 与 postgres 不同

ruby-on-rails - 如何从 Rails 中的索引更新记录

ruby - 如何在 Ruby 中写入文件?

ruby - 使用适用于 ruby​​ 的 aws sdk 创建实例时,如何为实例命名?

ruby - 我如何 "force"我的 Rails 3 应用程序使用 1.9.2

ruby-on-rails-3 - 如何在 CSS 中使用 wicked_pdf 的背景图像