Проблема с параметром декодирования 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, но он доставляет.

надеюсь, что это поможет.


преобразование хэша в JSON с помощью to_json


ошибка говорит вам, что ActiveSupport:: JSON.декодировать ожидает, что будет предоставлена строка, но не может принудить аргумент, который вы предоставляете в строку. Аргумент, предоставленный ему здесь, - "product_params", который возвращает ActionController::Parameters (слабо обернутый хэш).

Если вы используете костяк стиля "из коробки", нет необходимости декодировать то, что публикуется в этом действии. Просто измените действие кому:

@product = Product.new(product_params)

структура вашего метода product_params указывает, что действие ожидает данные, которые вы публикуете выглядеть так:

{
  product: {
    title: "Foo",
    data: "bar"
  }
}

и что ваша модель продукта имеет два атрибута ,которые будут заполнены.новое: название и данные.

Если вы явно кодируете что-то в JSON на стороне клиента, вам нужно выяснить, какой параметр POST он передается как и декодировать его на сервере (опять же-есть почти конечно, не очень хорошая причина, чтобы прыгать через обручи, как это).