对于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
当网址带有后缀时,此功能非常有用:/users.json
通过我的Api::UsersController
àlaapi_users_path
; /users.html
通过我的UsersController
àlausers_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缺少后缀时捕获的约束,当我导航到{时,我觉得我不应该 - request.format == :html
报告为真{1}}。为什么第二个约束没有捕捉到它?
另外,虽然我可以通过改变这两个的顺序来“修复”这个,但我更愿意知道为什么我的约束不能正常工作。
有没有人知道如何有效地强制执行这些约束以有效地打开任何格式,不仅仅是url后缀,还是有一个不包含格式后缀的显式约束?
答案 0 :(得分:3)
我认为你不需要第二个约束块(:html
的那个)。我认为这应该做你想要的:
scope module: :api, as: :api do
constraints format: :json do
resources :users
end
end
resources :users
答案 1 :(得分:1)
扩展Jeremy的答案..如果在路径的api范围之前插入用户默认的html路由怎么办?
等
resources :users
scope module: :api, as: :api do
constraints format: :json do
resources :users
end
end
奇怪的是,这适合我!
答案 2 :(得分:1)
将无后缀默认格式设置为json
应该可以满足您的需求。
scope module: :api, as: :api, defaults: { format: :json} do
constraints format: :json do
resources :users
end
end
只有明确的.html后缀请求才会以此资源结束
resources :users