1
votes

Given a Rails backend and a Vue frontend, how can I POST to the nested ImageAttachment class? A Photo can have one ImageAttachment. I have these strong parameters set up, it feels like the issue is there but I can't find anything.

def photo_params
  params.require(:photo).permit(
    image_attachment: %i[data crop_x crop_y crop_width crop_height revert]
  )
end

This is the Vue function that attaches the child (ImageAttachment) info to the parent Photo.

uploading: function (file, xhr, formData) {
  formData.append('photo[image_attachment][data]', file)
}

But how it stands gives this error:

ActiveRecord::AssociationTypeMismatch - ImageAttachment(#70277552586900) expected, got {"data"=>#, @original_filename="30594959_1160903097380019_7860735199103942656_o.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"photo[image_attachment][data]\"; filename=\"30594959_1160903097380019_7860735199103942656_o.jpg\"\r\nContent-Type: image/jpeg\r\n">} which is an instance of ActiveSupport::HashWithIndifferentAccess(#70277506611620):

2

2 Answers

0
votes

I had AssociationTypeMismatch. I was using accept_nested_attributes in model. In your example image_attachment stands for association probably, thats why the error. I would use attr_accessor : imgattachment and in controller something like this

photo = Photo.new
img_attachment = ImageAttachment.new
img_attachment.data = params[:imgattachment][:data]
photo.image_attachment << img_attachment

My topic: ActiveRecord::AssociationTypeMismatch when trying to register user using devise

Seems its problem with accept_nested_attributes

0
votes

So the way around this is to leverage the _attributes. JS:

uploading: function (file, xhr, formData) {
  formData.append('photo[image_attachment_attributes][data]', file)
}

Model:

accepts_nested_attributes_for :image_attachment, allow_destroy: true

Controller:

def create
  if @photo.update_attributes!(photo_params)
    response = @photo.reload && @photo.exists? ? @photo.for_vue : nil
    render json: { photo: response }, status: 200
  else
    render json: { error: @photo.errors }, status: 400
  end
end

private

def photo_params
  params.require(:photo).permit(
    image_attachment_attributes:
      %i[data crop_x crop_y crop_width crop_height revert]
  )
end