对于 Reasons™,我想让一个控制器处理 html 请求,另一个处理 json api 请求。
我的路线中有这个:
scope module: :api, as: :api do
constraints format: :json do
resources :users
end
end
constraints format: :html do
resources :users
end
当 url 带有后缀时,这很有效:/users.json
通过 my Api::UsersController
à la api_users_path
; /users.html
通过我的UsersController
à la users_path
。
但是,当 url 中没有后缀时,这不会像预期的那样运行。将约束实现为 lambda 显示出问题:
#=> visiting /users
scope module: :api, as: :api do
constraints ->(request){ puts "In api: #{request.format}"; request.format == :json } do
resources :users
end
end
constraints ->(request){ puts "In html: #{request.format}"; request.format == :html } do
resources :users
end
#=> In api: text/html
#=> (request.format == :json) => false
但它最终出现在 api 控制器中。
如果没有任何约束匹配,则不要摆弄自定义约束类或 lambdas 或任何东西会阻止 rails 选择定义的第一个路由。
我找不到一种方法来编写一个在 url 缺少后缀时捕获的约束,而且我觉得我不应该这样做——<code>request.format == :html 在我导航时报告为真到/users
. 为什么第二个约束没有抓住它?
另外,虽然我可以通过改变这两个的顺序来“解决”这个问题,但我更想知道为什么我的约束不能正常工作。
有谁知道如何以不同的方式强制执行这些约束以有效地打开任何格式,而不仅仅是 url 后缀,或者有一个不包含格式后缀的显式约束?