AssociationTypeMisMatch: как создать объект и связанные (вложенные) объекты с помощью RESTful API (Rails), принимающего JSON? - PullRequest
0 голосов
/ 13 декабря 2018

Я пробовал это в течение нескольких часов, но я не могу понять, что я делаю неправильно.Я упростил мой пример для демонстрационных целей.

Создание только объекта Car работает, но присоединение к нему Wheel объектов приводит к ActiveRecord::AssociationTypeMisMatch.

с учетом классов Car и Wheel

class Car < ApplicationRecord
  has_many :wheels

  validates :max_speed_in_kmh,
            :name, presence: true
end


class Wheel < ApplicationRecord
  has_one :car

  validates :thickness_in_cm,
            :place, presence: true
end

и CarsController

module Api
  module V1
    class CarsController < ApplicationController

      # POST /cars
      def create
        @car = Car.create!(car_params)
        json_response(@car, :ok)
      end

      private

      def car_params
        params.permit(
          :max_speed_in_kmh,
          :name,
          { wheels: [:place, :thickness_in_cm] }
        )
      end
    end
  end
end

echo '{"name":"Kid","max_speed_in_kmh":300,"wheels":[{"thickness_in_cm":70, "place":"front"},{"thickness_in_cm":75, "place":"rear"}]}' | http POST httpbin.org/post

... "json": { "max_speed_in_kmh": 300, "name": "Kid", "wheels": [ { "place": "front", "thickness_in_cm": 70 }, { "place": "rear", "thickness_in_cm": 75 } ] }, ...

JSON хорошо сформирован.Оставляя колеса, объект Car создается и сохраняется.С объектами Wheel контроллер возвращает

status 500 error Internal Server Error exception #<ActiveRecord::AssociationTypeMismatch: Wheel(#70285481379180) expected, got {"place"=>"front", "thickness_in_cm"=>75} which is an instance of ActiveSupport::HashWithIndifferentAccess(#70285479411000)>

1 Ответ

0 голосов
/ 13 декабря 2018

Если вы хотите создать автомобиль вместе с колесами, вам нужно использовать accepts_nested_attributes_for

Добавить в модель автомобиля accepts_nested_attributes_for :wheels и изменить сильные параметры на

  def car_params
    params.permit(
      :max_speed_in_kmh,
      :name,
      { wheels_attributes: [:id, :place, :thickness_in_cm] }
    )
  end
...