Rails路由:指定none时的格式约束

时间:2013-10-11 19:31:51

标签: ruby-on-rails routing ruby-on-rails-4 rails-routing

对于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后缀,还是有一个不包含格式后缀的显式约束?

3 个答案:

答案 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