web-dev-qa-db-ja.com

Rails jQueryからJSONを正しくデコードしない(配列は整数キーを持つハッシュになります)

POST jQuery to Railsを使用したJSONオブジェクトの配列を作成するたびに、この問題が発生します。配列を文字列化すると、jQueryが正しく機能していることがわかります。

_"shared_items"=>"[{\"entity_id\":\"253\",\"position\":1},{\"entity_id\":\"823\",\"position\":2}]"
_

しかし、配列をAJAX呼び出しのデータとして送信するだけの場合、次のようになります。

_"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}
_

一方、単純な配列を送信するだけで機能します:

_"shared_items"=>["entity_253"]
_

なぜRailsその奇妙なハッシュに配列を変更するのですか?頭に浮かぶ唯一の理由は、Railsが存在しないために内容を正しく理解できないことです(jQueryのコールでそれを設定する方法はありますか?)ここに入力します。

_Processing by SharedListsController#create as 
_

ありがとうございました!

更新:文字列ではなく配列としてデータを送信しており、配列は.Push()関数を使用して動的に作成されます。 _$.post_と_$.ajax_、同じ結果と試みました。

88
aledalgrande

誰かがこれにつまずいてより良い解決策を望む場合、.ajax呼び出しで「contentType: 'application/json'」オプションを指定し、RailsがJSONオブジェクトを整数に変換せずに適切に解析するようにできます。すべての文字列値を持つハッシュを-keyed。

だから、要約し、私の問題は、このことでした。

$.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}]}
});

物事を解析_ _が生じたRails:

Parameters: {"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}}

この一方で(注:私たちは今、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}]})
});

railsの中ニースオブジェクト内の結果:

Parameters: {"shared_items"=>[{"entity_id"=>"253", "position"=>1}, {"entity_id"=>"823", "position"=>2}]}

_のRails 3で私にとってこの作品は、Ruby 1.9.3。

165
swajak

少し古い質問が、私は今日これで自分自身を戦った、そしてここで私が思いついた答えだ:私はこれは少し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}]}

});
_

JQueryが投稿する値は、次のようになります(Firebug-of-choiceでリクエストを見ると)、次のようなフォームデータが得られます。

_shared_items%5B0%5D%5Bentity_id%5D:1
shared_items%5B0%5D%5Bposition%5D:1
_

あなたが買ってあげることCGI.unencode場合

_shared_items[0][entity_id]:1
shared_items[0][position]:1
_

これは、jQueryがJSONのキーがフォーム要素名であり、「user [name]」という名前のフィールドがあるかのように扱う必要があると考えるからだと思います。

彼らはあなたRailsアプリ、Railsブラケットを見て、フィールド名の最も内側のキー(「1」を保持するためのハッシュを作成しに来るので、 jQueryの "親切")を追加。

とにかく、私は次のように私の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}])},
  }
});
_

どの勢力jQueryのは、このJSONであると考えてあなたが、合格することを完全に、そしてないそれが取ると、フォームのフィールド名にすべてのキーを有効にする必要がありますJavascriptのオブジェクト。

ただし、それはRails側で物事が少し異なることを意味します。これは、params [:data]でJSONを明示的にデコードする必要があるためです。

しかし、それはOKです。

_ActiveSupport::JSON.decode( params[:data] )
_

TL; DR:したがって、解決策は次のとおりです。jQuery.ajax()呼び出しのdataパラメーターで、jQueryにJSON配列を渡す代わりに、{"data": JSON.stringify(my_object) }を明示的に実行します(ここでそれはあなたがそれで何をしたいのか間違って推測します。

11
RyanWilcox

私はちょうどで、この問題に遭遇した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
}
6
jessepinho

あなたが強いのパラメータを使用する場合、以下の方法が有用である可能性があり

def safe_params
  values = params.require(:shared_items)
  values = items.values if items.keys.first == '0'
  ActionController::Parameters.new(shared_items: values).permit(shared_items: [:entity_id, :position]).require(:shared_items)
end
1
Eugene

JSON文字列をRailsコントローラーアクションに取得しようとしていますか?

私はRailsはハッシュでやっているかわからないんだけど、あなたは問題を動き回るとJavascript/JSONオブジェクトを作成する(JSON文字列ではなく)と送信することによって、より多くの運を持っているかもしれませんそれを通して、あなたのAjax呼び出しのためのデータをパラメータとして。

myData = {
  "shared_items":
    [
        {
            "entity_id": "253",
            "position": 1
        }, 
        {
            "entity_id": "823",
            "position": 2
        }
    ]
  };

あなたは、AJAXを経由して、これを送信したいなら、あなたはこのような何かをするだろう。

$.ajax({
    type: "POST",
    url: "my_url",    // be sure to set this in your routes.rb
    data: myData,
    success: function(data) {          
        console.log("success. data:");
        console.log(data);
    }
});

それが明示的に指定するのは良いことだが、上記のAjaxスニペットと注意、jQueryのは、dataTypeとのインテリジェントな推測を行います。

いずれにしても、コントローラーアクションで、paramsハッシュで渡したJSONオブジェクトを取得できます。

params[:shared_items]

例えば。このアクションは、あなたにあなたのJSONオブジェクトの背中を吐くます。

def reply_in_json
  @shared = params[:shared_items]

  render :json => @shared
end
0
australis

使用 ラックjqueryの-のparams 宝石(免責事項:私は著者です)。これは、整数キー付きハッシュになって配列のあなたの問題を解決します。

0
Caleb Clark

あなたはparsed_json = ActiveSupport::JSON.decode(your_json_string)やって考えられていますか?あなたはものにあなたが使用することができますについて、他の方法を送信する場合は.to_jsonデータをシリアライズします。

0