Пользовательские параметры в URL для действия «показать»

Я работаю над реализацией SEO-иерархии, что означает, что мне нужно добавлять параметры перед действием show.

Вариант использования — это поисковый сайт со структурой URL:
/cars/(:brand)/=> страница со списком
/cars/(:brand)/(: model_name)?s=query_params=> поисковое действие
/cars/:brand/:model_name/:variant/:id=> действие автосалона

Моя задача сделать шоу URL-адреса действий работают без необходимости предоставления:brand, :model_nameи:variantв качестве отдельных аргументов. Они всегда доступны в виде значений ресурса.

Что у меня есть: /cars/19330-Audi-A4-3.0-TDI

Что я хочу /cars/Audi/A4/3.0-TDI/19330

Раньше route.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.brand, model_name: car.model_name, variant: 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

Маршрут работает нормально, т.е. /автомобили/Ауди/А4/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 в действительную ссылку.

10
задан Jonas Nielsen 26 March 2012 в 09:31
поделиться