Search code examples
ruby-on-railsrspecrspec-rails

Request Spec failing on Association - Rails 5 API


I've got a request spec failing on a model with an association; when I binding.pry into it I can manually create the record with the same parameters, but when I pass them through the post '/path/model' request, it fails and says the association should exist. That's good - I want the association to be required. But the post action seems to be unable to pass.

# job model
belongs_to :worker
validates :title, presence: true

# worker model
has_many :jobs

# jobs controller
# POST /jobs
def create
  @job = Job.create!(job_params)
  json_response(@job, :created)
end

# jobs request spec
describe "POST /v1/jobs" do
  context "when the request is valid" do
    before {
      post '/v1/jobs', params: {
        title: "Whatever",
        worker_id: Worker.first.id,
      }
    }

    it "creates a job" do
      puts request.body.read 
      puts response.body
      expect(json["title"]).to eq("Whatever")
    end

    it "returns status code 201" do
      expect(response).to have_http_status(201)
    end
  end
end

These tests both fail. The result of the puts statements above is:

title=Whatever&worker_id=21
{"message":"Validation failed: Worker must exist"}

If I put a binding.pry there instead, the following successfully creates a Job:

Job.create(title: "Whatever", worker_id: Worker.first.id)

My migrations are:

# jobs migration
create_table :jobs do |t|
  t.references :worker, index: true
  t.text :title
end

# worker migration
create_table :workers do |t|
  t.text :first_name
  ...
end

What am I missing here? I know that the belongs_to association is now non-optional in Rails 5, but again, I want that. So I don't want to flag it optional just to get my tests to pass. Any ideas?


Solution

  • Turns out this was a problem in the controller; I'm using strict parameters and didn't have the worker_id in the list of permitted params. Easy to overlook but it's a trap! Hope this helps someone else, especially since all the advice about the belongs_to association for Rails 5 says, "just make it optional."