জেলগুলি jQuery থেকে সঠিকভাবে জেএসনকে ডিকোড করছে না (পুরোপুরি কীগুলির সাথে অ্যারে হ্যাশ হয়ে উঠছে)


89

প্রতিবার আমি jQuery এর সাথে রেলে JSON অবজেক্টগুলির একটি অ্যারে পোস্ট করতে চাইলে আমার এই সমস্যাটি রয়েছে। যদি আমি অ্যারেটিকে আরও শক্তিশালী করি তবে আমি দেখতে পাচ্ছি যে jQuery এর কাজটি সঠিকভাবে করছে:

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

তবে আমি যদি অ্যারেটিকে কেবল এজাক্স কলের ডেটা হিসাবে প্রেরণ করি তবে:

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

আমি যদি কেবল একটি সরল অ্যারে প্রেরণ করি তবে এটি কাজ করে:

"shared_items"=>["entity_253"]

কেন পিলগুলি অ্যারেটিকে অদ্ভুত হ্যাশে পরিবর্তন করছে? মাথায় আসার একমাত্র কারণটি হ'ল রেলগুলি সামগ্রীগুলি সঠিকভাবে বুঝতে পারে না কারণ এখানে কোনও প্রকার নেই (jQuery কলটিতে সেট করার কোনও উপায় আছে কি?):

Processing by SharedListsController#create as 

ধন্যবাদ!

আপডেট: আমি একটি অ্যারে হিসাবে ডেটা প্রেরণ করছি, একটি স্ট্রিং নয় এবং .push()ফাংশনটি ব্যবহার করে অ্যারেটি গতিশীলভাবে তৈরি করা হয়েছে । চেষ্টা করেছেন $.postএবং $.ajaxএকই ফলাফল।

উত্তর:


169

যদি কেউ এতে হোঁচট খায় এবং এর থেকে আরও ভাল সমাধান চান, আপনি .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}]}
});

এর ফলে কারগুলি জিনিসগুলি বিশ্লেষণ করে:

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

যদিও এটি (দ্রষ্টব্য: আমরা এখন জাভাস্ক্রিপ্ট অবজেক্টকে স্ট্রাইফাই করছি এবং একটি সামগ্রীর ধরণ উল্লেখ করছি, সুতরাং রেলগুলি কীভাবে আমাদের স্ট্রিংকে পার্স করতে পারে তা জানতে পারে):

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

রেলগুলিতে একটি দুর্দান্ত অবজেক্টের ফলাফল:

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

এটি আমার জন্য রুবেল ১.৯.৩-তে রেলস 3 এ কাজ করে।


4
এটি রইলগুলির জন্য সঠিক আচরণের মতো বলে মনে হচ্ছে না, জ্যাকুয়েরির কাছ থেকে জেএসএন গ্রহণ করা রেল অ্যাপ্লিকেশনগুলির পক্ষে একটি সাধারণ সাধারণ বিষয় given কেন রেয়েলস এইভাবে আচরণ করে সে সম্পর্কে কোনও ডিফেন্সেবল যুক্তি আছে? দেখে মনে হচ্ছে ক্লায়েন্ট-সাইড জেএস কোড অকারণে হুপসের মধ্য দিয়ে ঝাঁপিয়ে পড়েছে।
জেরেমি বার্টন

4
আমি মনে করি উপরের মামলায় অপরাধী jQuery। আইর্ক জিকুয়েরিতে Content-Typeঅনুরোধটির সেট করা ছিল না application/json, তবে পরিবর্তে এইচটিএমএল ফর্ম হিসাবে ডেটা পাঠাচ্ছিল? এতদূর ফিরে চিন্তা করা শক্ত। Content-Typeসঠিক মান নির্ধারণের পরে, জেলগুলি ঠিক কাজ করছিল, এবং প্রেরিত ডেটা বৈধ JSON ছিল।
সোয়াজাক

4
আপনি দেখতে চান যে কেবলমাত্র @sjajak বস্তুটিকে আরও শক্তিশালী করেছে তবে তাও উল্লেখ করতে চানcontentType: 'application/json'
রজার ল্যাম

4
ধন্যবাদ @ রজারল্যাম, আমি আরও উন্নত আশা করি বর্ণনা করার সমাধানটি আপডেট করেছি
স্বজাক

4
@ সোয়াজাক: আপনাকে অনেক ধন্যবাদ! তুমি আমার দিন বাঁচিয়েছ! :)
কুলগার

12

সামান্য পুরানো প্রশ্ন, তবে আমি আজ এটির সাথে লড়াই করেছি এবং আমি এখানে উত্তরটি নিয়ে এসেছি: আমি বিশ্বাস করি এটি কিছুটা jQuery এর দোষ, তবে এটি কেবল এটিই স্বাভাবিক যা করছেন এটিই করছে। আমার অবশ্য একদম কাজ আছে।

নিম্নলিখিত jQuery আজাক্স কল দেওয়া হয়েছে:

$.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 যে মানগুলি পোস্ট করবে সেগুলি এর মতো দেখতে পাবেন (যদি আপনি আপনার ফায়ারব্যাগ-অফ-পছন্দের অনুরোধটি দেখেন) আপনাকে এমন ফর্ম ডেটা দেবে:

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 এ থাকা কীগুলি ফর্ম উপাদানগুলির নাম, এবং এটি তাদের সাথে এমন আচরণ করা উচিত যেন আপনার "ব্যবহারকারী [নাম]" নামে একটি ক্ষেত্র রয়েছে।

সুতরাং তারা আপনার রেল অ্যাপগুলিতে আসে, রেলগুলি বন্ধনীগুলি দেখে এবং ক্ষেত্রের নামের অভ্যন্তরীণ কীটি ধরে রাখার জন্য একটি হ্যাশ তৈরি করে ("1" যে jQuery "সহায়কভাবে" যুক্ত হয়েছে)।

যাইহোক, আমি আমার এজ্যাক্স কলটি নীচের উপায়ে তৈরি করে এই আচরণটি পেয়েছি;

$.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 একটি হল মান যে আপনার পাস সম্পূর্ণরূপে চান, এবং না একটি জাভাস্ক্রিপ্ট অবজেক্ট তা গ্রহণ এবং ফর্ম ফিল্ডের নাম সব কী চালু করতে হবে।

যাইহোক, এর অর্থ রেলের পাশের জিনিসগুলি কিছুটা আলাদা are কারণ আপনার স্পষ্টতই JSON কে প্যারামে ডিকোড করতে হবে [: ডেটা]।

তবে এটি ঠিক আছে:

ActiveSupport::JSON.decode( params[:data] )

টিএল; ডিআর: সুতরাং, সমাধানটি হ'ল: আপনার jQuery.ajax () কলের ডেটা প্যারামিটারে {"data": JSON.stringify(my_object) }, JSON তে জেএসএন অ্যারে ফিড না করে স্পষ্ট করে বলুন (যেখানে এটি আপনি কী করতে চান তা ভুল অনুমান করে।


শীর্ষস্থানীয় আরও ভাল সমাধান নীচে নীচে নীচে দেওয়া আছে @ স্বজাক।
ইভেন্ট_জেআর

7

আমি কেবল 4 ইস্যুগুলি নিয়ে এই ইস্যুটিতে ছড়িয়েছি your আপনার প্রশ্নের স্পষ্টভাবে উত্তর দেওয়ার জন্য ("কেন রেলগুলি সেই অদ্ভুত হ্যাশগুলিতে অ্যারে পরিবর্তন করছে?"), অ্যাকশন কন্ট্রোলারগুলির বিষয়ে রেল গাইডের বিভাগ 4.1 দেখুন :

মানগুলির একটি অ্যারে প্রেরণ করতে, মূল নামে একটি ফাঁকা জোড়া বর্গাকার বন্ধনী "[]" যুক্ত করুন।

সমস্যাটি হ'ল, jQuery খালি স্কোয়ার বন্ধনীগুলির পরিবর্তে সুস্পষ্ট অ্যারে সূচকগুলির সাথে অনুরোধটিকে বিন্যাস করে। সুতরাং, উদাহরণস্বরূপ, প্রেরণের পরিবর্তে shared_items[]=1&shared_items[]=2এটি প্রেরণ করে shared_items[0]=1&shared_items[1]=2। পাগল, অ্যারের সূচকগুলি এবং অ্যারে সূচকের বদলে হ্যাশ কী হিসেবে ব্যাখ্যা করে তাদের উদ্ধার একটি অদ্ভুত রুবি হ্যাশ মধ্যে অনুরোধ বাঁক: { shared_items: { '0' => '1', '1' => '2' } }

আপনার যদি ক্লায়েন্টের নিয়ন্ত্রণ না থাকে তবে আপনি হ্যাশটিকে একটি অ্যারে রূপান্তর করে সার্ভার সাইডে এই সমস্যাটি সমাধান করতে পারেন। আমি এটি কীভাবে করেছি তা এখানে:

shared_items = []
params[:shared_items].each { |k, v|
  shared_items << v
}

1

আপনি যদি শক্তিশালী পরামিতি ব্যবহার করেন তবে নিম্নলিখিত পদ্ধতিটি সহায়ক হতে পারে

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

0

আপনি কি বিবেচনা করেছেন parsed_json = ActiveSupport::JSON.decode(your_json_string)? আপনি যদি অন্যভাবে স্টাফ প্রেরণ করেন তবে আপনি .to_jsonডেটাটি সিরিয়াল করতে ব্যবহার করতে পারেন ।


4
হ্যাঁ বিবেচনা করা হয়েছে, তবে ম্যানুয়ালি এনকোড / ডিকোড না করেই রেলগুলিতে এটি করার কোনও "সঠিক উপায়" আছে কিনা তা জানতে চেয়েছিলেন।
এলেডালগ্রান্ডে

0

আপনি কি কেবল জেলসন স্ট্রিংটিকে একটি রেল নিয়ন্ত্রক পদক্ষেপে নিয়ে যাওয়ার চেষ্টা করছেন?

আমি নিশ্চিত না যে রেলগুলি হ্যাশ দিয়ে কী করছে, তবে আপনি সমস্যাটি পেতে পারেন এবং জাভাস্ক্রিপ্ট / জেএসএন অবজেক্ট তৈরি করেছেন (জেএসএন স্ট্রিংয়ের বিপরীতে) তৈরি করে এবং এটি আপনার অ্যাজ্যাক্সের জন্য ডেটা প্যারামিটার হিসাবে পাঠিয়েছেন more কল

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

আপনি যদি এজাক্সের মাধ্যমে এটি প্রেরণ করতে চান তবে আপনি এরকম কিছু করতে পারেন:

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

উপরের অজ্যাক্স স্নিপেটের সাথে নোট করুন, jQuery ডেটা টাইপ সম্পর্কে একটি বুদ্ধিমান অনুমান করবে, যদিও এটি স্পষ্টভাবে নির্দিষ্ট করে দেওয়া ভাল।

যে কোনও উপায়েই, আপনার নিয়ামক পদক্ষেপে, আপনি JSON অবজেক্টটি প্যারাম হ্যাশ দিয়ে পাস করতে পারেন, অর্থাত্‍

params[:shared_items]

উদাহরণস্বরূপ এই ক্রিয়াটি আপনার জাসন অবজেক্টটিকে আপনার দিকে ফিরিয়ে দেবে:

def reply_in_json
  @shared = params[:shared_items]

  render :json => @shared
end

ধন্যবাদ, তবে এখনই আমি এটি করছি (আপডেট দেখুন) এবং এটি কার্যকর হয় না।
এলেডালগ্রান্ডে

0

ব্যবহার করুন আলনা-jQuery-প্যারাম মণি (দাবিত্যাগ: আমি লেখক নই)। এটি আপনার অ্যারেগুলির পূর্ণসংখ্যার কীগুলির সাথে হ্যাশ হয়ে উঠার বিষয়টি ঠিক করে।


লিঙ্ক স্থাপনের পরিবর্তে কিছু কোড স্নিপেট সরবরাহ করা আরও ভাল
বিকাশদীপ সিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.