Трохи старе запитання, але я сьогодні сам з цим боровся, і ось відповідь, яку я придумав: я вважаю, що це трохи винна 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), ви отримаєте дані форми, які виглядають так:
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 є іменами елементів форми, і що він повинен розглядати їх так, ніби у вас є поле з ім'ям "користувач [ім'я]".
Тож вони потрапляють у ваш додаток 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 справи йдуть трохи інакше, тому що вам потрібно явно декодувати JSON у параметрах [: data].
Але це нормально:
ActiveSupport::JSON.decode( params[:data] )
TL; DR: Отже, рішення полягає в: у параметрі даних для вашого виклику jQuery.ajax () виконайте {"data": JSON.stringify(my_object) }
явно, замість того, щоб подавати масив JSON у jQuery (де він неправильно здогадується, що ви хочете з ним зробити.