Я работаю над реализацией 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 в действительную ссылку.