Я работаю над реализацией SEO-hiarchy, а это значит, что мне нужно предварительно добавить параметры для действия 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
Раньше это было как 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.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
Маршрут работает нормально, например, /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 в действительную ссылку.