Search code examples
ruby-on-railsrubyruby-on-rails-4ruby-on-rails-5postman

Rails API - POST request using multipart/form-data format gives ActionController::ParameterMissing


I am able to post the following body in raw JSON format to my API without any issues:-

{
    "job":{
    "title": "Job 1",
    "description": "Job 1",
    "date": "2021-03-11T16:59:03.194Z",
    "budget": "0.0",
    "awarded": true,
    "client_id": 1,
    "location_id": 86,
    "tag_ids":[25]
    }
}

I want to make use of the file-upload option in postman now, as I've added images to this object. You can only attach files via Postman when using multipart/form-data Content-Type - yet it does not work and tells me the "job" param is missing..

I've set the keys of the hash like:-

job[title]
job[description]
job[date]

..etc.

I leave the Content-Type blank initially so it defaults to the correct one (multipart/form-data), which gives:-

"status": 400,
"error": "Bad Request",
"exception": "#<ActionController::ParameterMissing: param is missing or the value is empty: job\nDid you mean?  controller

When I set the Content-Type explicitly to application/json, I get:-

"status": 400,
    "error": "Bad Request",
    "exception": "#<ActionDispatch::Http::Parameters::ParseError: 783: unexpected token at '----------------------------632616788333464717206731\r\nContent-Disposition: form-data; name=\"job[title].......etc

My controller:-

  def create
    @job = Job.new(job_params)
    if @job.save
      render json: @job, status: :created
    else
      render json: @job.errors, status: :unprocessable_entity
    end
  end

  def job_params
    params.require(:job).permit(:title, :description, :date, :budget, :awarded, :client_id, :location_id, tag_ids: [])
  end

What I've tried:-

  • Formatted the form-data keys without prefixing job - doesn't help.

Images:-

Failed POST using form-data

Successful POST using raw JSON


Solution

  • I found the solution to this after realising the output cURL script for my failing request actually worked.

    The problem was in my headers - the default Content-Type in auto-generated headers was set to:-

    multipart/form-data; boundary=<calculated when request is sent>

    I had unchecked that, and added my own with:-

    multipart/form-data

    Leaving it as the default resolved my issue.