Rails 与可选路径参数同名的查询参数

Rails query parameter with same name as optional path parameter

假设,我在 routes.rb

中有这段代码
get "/items/(:brand)", to: "items#index", as: :items

我不能改变这条路线,因为有时我需要路径中有品牌的网址(不是查询中)。 我可以这样创建路径吗:

/items?brand=TestBrand

但不是这个:

/items/TestBrand

通过路由助手?

items_path(brand: "TestBrand") 给出第二个变体。

默认支持 "get" 中的其他参数,因此也许您可以使用

get "/items", to: "items#index", as: :items

resources :items, only: [:index]

并使用您提供的路径助手:

items_path(brand: "TestBrand")

回答你的问题 - 是的,你可以

get "/items", to: "items#index", as: :items

下面的路由助手将创建

items_path(brand: "TestBrand")
#=> items?brand=TestBrand

注意:

如果您正在使用:

recourses :items

你一定已经有了这个

这不是一个很好的解决方案,因为它违反了 RESTful 约定。

在 Rails 风格中,REST GET /resource_name/:id 映射到显示路径。在 get "/items/(:brand)", to: "items#index", as: :items 的情况下,当路由器匹配请求并且第一个声明的路由将获胜时,这会产生歧义(段是项目 ID 还是品牌?),这几乎是不可取的。

更好的解决方案是将其声明为嵌套资源:

resources :brands, only: [] do
  resources :items, only: [:index], module: :brands
end

    Prefix Verb URI Pattern                       Controller#Action
brand_items GET  /brands/:brand_id/items(.:format) brands/items#index

# app/controllers/brands/items_controller.rb
module Brands
  class ItemsController < ::ApplicationController
    before_action :set_brand

    # GET /brands/:brand_id/items
    def index
      @items = @brand.items
    end

    def set_brand
      @brand = Brand.find(params[:brand_id])
    end
  end
end