6

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

4

3 回答 3

3

我认为您不需要第二个约束块( for 的那个:html)。我认为这应该做你想要的:

scope module: :api, as: :api do
  constraints format: :json do
    resources :users
  end
end

resources :users
于 2013-10-12T04:47:39.653 回答
1

扩展杰里米的答案.. 如果您在路由的 api 范围之前插入用户默认的 html 路由怎么办?

喜欢,

resources :users
scope module: :api, as: :api do
  constraints format: :json do
    resources :users
  end
end

奇怪的是,这对我有用!

于 2013-10-14T14:41:30.223 回答
1

将无后缀的默认格式设置为json应该可以满足您的需求。

scope module: :api, as: :api, defaults: { format: :json} do
  constraints format: :json do
    resources :users
  end
end

只有明确的 .html 后缀请求才会在此资源中结束

resources :users
于 2014-11-04T22:25:00.120 回答