我的应用程序中有一个主干模型,它不是一个典型的平面对象,它是一个很大的嵌套对象,我们将嵌套部分存储在MySQL数据库的文本列中。
我想在Rails API中处理JSON编码/解码,这样从外部看,您可以POST/GET这个大型嵌套JSON对象,即使它的一部分被存储为字符串JSON文本。
但是,我遇到了一个问题,Rails神奇地将空数组转换为nil
值。例如,如果我发布以下内容:
{
name: "foo",
surname: "bar",
nested_json: {
complicated: []
}
}
我的Rails控制器看到了以下内容:
{
:name => "foo",
:surname => "bar",
:nested_json => {
:complicated => nil
}
}
所以我的JSON数据被修改了..
以前有没有人遇到过这个问题?为什么Rails要修改我的帖子数据?
更新
下面是他们这样做的地方:
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/request.rb#L288
这是他们为什么这么做的原因:
https://github.com/rails/rails/pull/8862
所以现在的问题是,在我的嵌套JSON API情况下,如何最好地处理这个问题?
发布于 2014-08-21 22:20:28
经过多次搜索,我发现从Rails4.1开始,您可以使用以下命令完全跳过deep_munge“特性”
config.action_dispatch.perform_deep_munge = false
我找不到任何文档,但您可以在此处查看此选项的介绍:https://github.com/rails/rails/commit/e8572cf2f94872d81e7145da31d55c6e1b074247
这样做可能存在安全风险,记录在这里:https://groups.google.com/forum/#!topic/rubyonrails-security/t1WFuuQyavI
发布于 2013-02-01 22:18:13
看起来这是一个最近引入的已知问题:https://github.com/rails/rails/issues/8832
如果你知道空数组在哪里,你可以总是在一个params[:...][:...] ||= []
过滤器中使用它。
或者,您可以将BackBone模型的to方法修改为nested_json方法,在发布之前使用JSON.stringify()
显式地将JSON值串起来,然后在before_filter中使用JSON.parse
手动将其解析出来。
丑陋,但它会起作用的。
发布于 2013-02-27 05:30:25
您可以自己重新解析参数,如下所示:
class ApiController
before_filter :fix_json_params # Rails 4 or earlier
# before_action :fix_json_params # Rails 5
[...]
protected
def fix_json_params
if request.content_type == "application/json"
@reparsed_params = JSON.parse(request.body.string).with_indifferent_access
end
end
private
def params
@reparsed_params || super
end
end
其工作方式是查找具有JSON content-type的请求,重新解析请求正文,然后拦截params
方法以返回重新解析的参数(如果存在)。
https://stackoverflow.com/questions/14647731
复制相似问题