ale*_*nde 89 arrays jquery post json ruby-on-rails
每次我想用jQuery向Jails发布一个JSON对象数组时,我就遇到了这个问题.如果我对数组进行字符串化,我可以看到jQuery正在正常工作:
"shared_items"=>"[{\"entity_id\":\"253\",\"position\":1},{\"entity_id\":\"823\",\"position\":2}]"
Run Code Online (Sandbox Code Playgroud)
但是如果我只是将它作为AJAX调用的数据发送给我:
"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}
Run Code Online (Sandbox Code Playgroud)
然而,如果我只发送一个普通数组,它的工作原理:
"shared_items"=>["entity_253"]
Run Code Online (Sandbox Code Playgroud)
为什么Rails将数组更改为那个奇怪的哈希?想到的唯一原因是Rails无法正确理解内容,因为这里没有类型(有没有办法在jQuery调用中设置它?):
Processing by SharedListsController#create as
Run Code Online (Sandbox Code Playgroud)
谢谢!
更新:
我将数据作为数组发送,而不是字符串,并使用该.push()函数动态创建数组.尝试$.post和$.ajax,相同的结果.
swa*_*jak 165
如果有人偶然发现并想要一个更好的解决方案,你可以在.ajax调用中指定"contentType:'application/json'"选项,并让Rails正确解析JSON对象,而不是将其整合到整数键哈希中,而不是 - 字符串值.
总而言之,我的问题是:
$.ajax({
type : "POST",
url : 'http://localhost:3001/plugin/bulk_import/',
dataType: 'json',
data : {"shared_items": [{"entity_id":"253","position":1}, {"entity_id":"823","position":2}]}
});
Run Code Online (Sandbox Code Playgroud)
导致Rails将事物解析为:
Parameters: {"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}}
Run Code Online (Sandbox Code Playgroud)
而这(注意:我们现在正在对javascript对象进行字符串化并指定内容类型,因此rails将知道如何解析我们的字符串):
$.ajax({
type : "POST",
url : 'http://localhost:3001/plugin/bulk_import/',
dataType: 'json',
contentType: 'application/json',
data : JSON.stringify({"shared_items": [{"entity_id":"253","position":1}, {"entity_id":"823","position":2}]})
});
Run Code Online (Sandbox Code Playgroud)
在Rails中产生一个很好的对象:
Parameters: {"shared_items"=>[{"entity_id"=>"253", "position"=>1}, {"entity_id"=>"823", "position"=>2}]}
Run Code Online (Sandbox Code Playgroud)
这适用于Ruby 1.9.3中的Rails 3.
Rya*_*cox 11
稍微陈旧的问题,但我今天自己也在与之斗争,这就是我想出的答案:我相信这只是jQuery的错误,但它只是在做它自然而然的事情.但是,我确实有一个解决方法.
鉴于以下jQuery ajax调用:
$.ajax({
type : "POST",
url : 'http://localhost:3001/plugin/bulk_import/',
dataType: 'json',
data : {"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}]}
});
Run Code Online (Sandbox Code Playgroud)
jQuery将发布的值看起来像这样(如果你看看你的Firebug选择中的请求)会给你看起来像这样的表单数据:
shared_items%5B0%5D%5Bentity_id%5D:1
shared_items%5B0%5D%5Bposition%5D:1
Run Code Online (Sandbox Code Playgroud)
如果你CGI.unencode你会得到
shared_items[0][entity_id]:1
shared_items[0][position]:1
Run Code Online (Sandbox Code Playgroud)
我相信这是因为jQuery认为JSON中的那些键是表单元素名称,并且它应该将它们视为具有名为"user [name]"的字段.
所以他们进入你的Rails应用程序,Rails看到括号,并构造一个哈希来保存字段名称的最里面的键(jQuery"帮助"添加的"1").
无论如何,我通过以下方式构建我的ajax调用来解决这个问题;
$.ajax({
type : "POST",
url : 'http://localhost:3001/plugin/bulk_import/',
dataType: 'json',
data : {"data": JSON.stringify({"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}])},
}
});
Run Code Online (Sandbox Code Playgroud)
这迫使jQuery认为这个JSON是一个你想要完全传递的值,而不是它必须采用的Javascript对象,并将所有键转换为表单字段名称.
但是,这意味着Rails方面的情况略有不同,因为您需要在params [:data]中显式解码JSON.
但那没关系:
ActiveSupport::JSON.decode( params[:data] )
Run Code Online (Sandbox Code Playgroud)
TL; DR:所以,解决方案是:在你的jQuery.ajax()调用的数据参数中,{"data": JSON.stringify(my_object) }明确地做,而不是将JSON数组提供给jQuery(它错误地猜测你想用它做什么).
我只是碰到了这个问题,使用Rails 4.要明确地回答你的问题("为什么Rails的改变阵列到陌生的哈希?"),请参阅第4.1节滑轨上的动作控制器指导:
要发送值数组,请在键名称后附加一对空方括号"[]".
问题是,jQuery使用显式数组索引格式化请求,而不是使用空方括号.因此,例如shared_items[]=1&shared_items[]=2,它发送而不是发送shared_items[0]=1&shared_items[1]=2.Rails看到数组索引并将它们解释为散列键而不是数组索引,将请求转换为奇怪的Ruby散列:{ shared_items: { '0' => '1', '1' => '2' } }.
如果您无法控制客户端,则可以通过将哈希转换为数组来解决服务器端的此问题.我是这样做的:
shared_items = []
params[:shared_items].each { |k, v|
shared_items << v
}
Run Code Online (Sandbox Code Playgroud)