Tôi đang làm việc để triển khai chế độ SEO, điều đó có nghĩa là tôi cần phải thêm thông số cho một hành động hiển thị.Thông số tùy chỉnh trong URL cho hành động hiển thị
Việc sử dụng hợp cụ thể là một trang web tìm kiếm nơi URL cấu trúc là:
/cars/(:brand)/
=> một danh sách trang
/cars/(:brand)/(:model_name)?s=query_params
=> tìm kiếm hành động
/cars/:brand/:model_name/:variant/:id
=> một chương trình xe hoạt động
My vấn đề là làm cho URL hoạt động của chương trình hoạt động mà không cần phải cung cấp:brand
, :model_name
và:variant
làm đối số riêng lẻ . Chúng luôn có sẵn từ các giá trị trên tài nguyên.
Những gì tôi có: /cars/19330-Audi-A4-3.0-TDI
Những gì tôi muốn /cars/Audi/A4/3.0-TDI/19330
Trước đây, đây là như thế nào routes.rb
trông giống như:
# Before
resources :cars. only: [:show] do
member do
get 'favourize'
get 'unfavourize'
end
Sau đây là nỗ lực đầu tiên của tôi:
# 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
Điều này giúp bạn có thể thực hiện:
cars_path(car, brand: car.brand, model_name: car.model_name, variant: car.variant)
Nhưng điều đó rõ ràng không thực sự lý tưởng.
Làm cách nào để thiết lập các tuyến đường (và có lẽ là phương pháp .to_param
?) Theo cách không khiến nhiệm vụ tẻ nhạt thay đổi tất cả các cuộc gọi link_to
?
Cảm ơn trước!
- CẬP NHẬT -
Với gợi ý @ tharrisson, đây là những gì tôi đã cố gắng:
# 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
Tuyến hoạt động tốt, ví dụ /cars/Audi/A4/3.0-TDI/19930
hiển thị đúng trang. Tuy nhiên, việc tạo liên kết với to_param
không hoạt động. Ví dụ:
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, (...)>})
Đường ray dường như không biết cách dịch to_param thành liên kết hợp lệ.
Đây là một câu hỏi thực sự tốt và tốt bằng văn bản. Tôi nghĩ rằng tôi có một ý tưởng và muốn chắc chắn rằng tôi đang đi đúng hướng (không có ý định chơi chữ). Có phải trường hợp bạn muốn có thể sử dụng 'cars_path (@car)' trong link_to của bạn và có nó tạo ra URL phân cấp tốt đẹp từ các khung nhìn của bạn, nhưng cũng có router nhận ra các URL "một phần" (ví dụ '/ cars/Audi') như một yêu cầu để liệt kê Audis? Hoặc là yêu cầu bổ sung cho liên kết_để nhận biết theo ngữ cảnh (ví dụ như vậy nó tạo liên kết đến biến thể/xe /: thương hiệu từ một số hành động của bộ điều khiển, nhưng URL đầy đủ của xe từ các hành động điều khiển khác? –
Cảm ơn, @tharrison. bạn đã có nó đúng, tôi muốn có thể sử dụng 'cars_path (@car)' trong 'link_to' của tôi. Hành động nào đang được kích hoạt có thể được kiểm soát bởi các ràng buộc trong' routes.rb'. Điều này có nghĩa là các url cho 'cars/Audi' không sử dụng 'cars_path' nhưng một cái gì đó như' brand_path (thương hiệu: "Audi") '. –
OK, đến đó, nhưng tôi không hoàn toàn có nó sau đó :-). Nếu bạn muốn sử dụng các tuyến đường được đặt tên như brand_path, đối số sẽ là một ví dụ của mô hình thương hiệu ... mặc dù điều đó có thể giống như 'brand_path (@ car.brand)'. Bạn có một mô hình thương hiệu và nguồn lực trong các tuyến đường cho điều đó không? –