Проблема с параметром декодирования JSON
у меня есть приложение rails 4, которое использует postgresql
. У меня также есть backbone.js
приложение, которое толкает в формате JSON в приложение rails 4.
вот мой контроллер:
def create
@product = Product.new(ActiveSupport::JSON.decode product_params)
respond_to do |format|
if @product.save
format.json { render action: 'show', status: :created, location: @product }
else
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
def product_params
params.require(:product).permit(:title, :data)
end
Я пытаюсь разобрать в формате JSON и вставьте продукт, но при вставке я получаю ошибку:
TypeError (no implicit conversion of ActionController::Parameters into String):
Спасибо за помощь!
3 ответов
ваш пробег может отличаться, но я исправил проблему smilar с помощью бандажного кода, как это:
hash = product_params
hash = JSON.parse(hash) if hash.is_a?(String)
@product = Product.new(hash)
особая проблема у меня была в том, что если бы я просто делал JSON.parse
на параметрах, содержащих объект, который я хотел создать, я получал эту ошибку во время модульного тестирования, но код работал нормально, когда мои веб-формы отправляли данные. В конце концов, потеряв 1 час на регистрации всевозможных глупостей, я понял, что мои модульные тесты каким-то образом проходили параметр запроса в "чистой" форме-а именно, объект был Hash
уже, но когда мои webforms (или ручное безголовое тестирование через cURL) сумбировали данные, параметры были такими, как вы ожидаете-строковое представление хэша.
использование этого небольшого фрагмента кода выше, конечно, bandaid, но он доставляет.
надеюсь, что это поможет.
ошибка говорит вам, что ActiveSupport:: JSON.декодировать ожидает, что будет предоставлена строка, но не может принудить аргумент, который вы предоставляете в строку. Аргумент, предоставленный ему здесь, - "product_params", который возвращает ActionController::Parameters (слабо обернутый хэш).
Если вы используете костяк стиля "из коробки", нет необходимости декодировать то, что публикуется в этом действии. Просто измените действие кому:
@product = Product.new(product_params)
структура вашего метода product_params указывает, что действие ожидает данные, которые вы публикуете выглядеть так:
{
product: {
title: "Foo",
data: "bar"
}
}
и что ваша модель продукта имеет два атрибута ,которые будут заполнены.новое: название и данные.
Если вы явно кодируете что-то в JSON на стороне клиента, вам нужно выяснить, какой параметр POST он передается как и декодировать его на сервере (опять же-есть почти конечно, не очень хорошая причина, чтобы прыгать через обручи, как это).