【发布时间】:2016-06-20 22:42:56
【问题描述】:
向我的 rails webapp 发出 POST/PATCH 请求时,我将数据作为 json 发送。例如这个 json 数据 {"name" => "Hallo", "status" => "admin"} 到一个名为 UsersController 的控制器。 wrap_parameters.rb 文件中的 wrap_parameters 设置为默认值:
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end
所以每个 json 数据都会像 "user" => {"name"=> "Hallo", "status" => "admin"} 这样包装。这是应该的。但是,当我调用位于 ApplicationController 中的名为 status 的自定义方法来检查服务器状态时,所有以下请求 json 数据都不会被包装在它们的控制器/模型名称哈希中,而是像 "application" => {"name"=> "Hallo", "status" => "admin"} 这样的哈希。
这适用于所有后续请求,直到我重新启动服务器。此外,如果我想保持“正确”的行为,我不能再次调用 ApplicationController 中的 status 方法,这将导致"application" => {...}wrapping。
我发现当我为状态方法的请求设置 Content-Type = text/html(之前是 Content-Type = application/json)时,以下请求没有被污染,这意味着我得到了正确的包装行为。
然而这很令人不安,因为当请求设置了 Content-Type = application/json 时,有人只需要调用 status 方法,并且后面的所有 POST/PATCH 请求都将不再工作。
我不知道这是否重要,但我在 routes.rb 中设置了以下内容:
namespace :api, defaults: {format: :json} do
namespace :v1 do
...
match "/status", to: "application#status", via: "get"
...
end
end
【问题讨论】:
-
尝试使用专用的 StatusController 而不是路由到 ApplicationController。 ApplicationController 通常只作为超类使用,不会被主动调用。
-
我很确定您的麻烦来自直接路由到 ApplicationController 上的方法。我猜这会将根名称设置为控制器的单数名称。在随后的调用中,根已经在超类中设置,因此不会在子类中再次设置。但是,我无法重现此行为。您使用的是哪个版本的导轨?
-
感谢您的帮助,非常感谢。你是对的,最好在 StatusController 中添加 status 方法,我会这样做。我使用 Rails 4.2.5.2。
-
我直接删除了所有到 ApplicationController 的路由。现在一切正常。
标签: ruby-on-rails ruby json ruby-on-rails-4 hash