Reputation: 542
I have the following relationship:
class Story < ApplicationRecord
has_many :characters
end
class Character < ApplicationRecord
belongs_to :story, required: true
end
And the following routes:
# config/routes.rb
Rails.application.routes.draw do
resources :stories do
resources :characters
end
end
Which ends up looking like this:
In my CharactersController
test, I have:
test "can create a new character" do
params = { story_id: @story.id, character: { name: "Billy" } }
post(story_characters_path, params: params)
# ... assertions follow
end
When it comes to the post(...)
command, I receive:
DRb::DRbRemoteError: No route matches {:action=>"index", :controller=>"characters"}, missing required keys: [:story_id]
It seems to be attempting the index action instead of the create action, despite the post
. Any ideas?
Upvotes: 1
Views: 180
Reputation: 101811
The correct way to call a nested POST or PATCH action is:
post story_characters_path(story_id: @story.id),
params: {
character: { name: "Billy" }
}
While post(story_characters_path(params))
might work you're actually putting the parameters into the query string instead of the request body where they should be.
In most cases you won't actually notice any difference as Rails merges the query string parameters with the request body into the params object but its still something that could let subtile bugs slip through.
For example if its a JSON request you won't get the correct types on the other end since query string parameters are always treated as strings.
Upvotes: 1
Reputation: 542
I think I figured it out. I needed to change the lines:
params = { story_id: @story.id, character: { name: "Billy" } }
post(story_characters_path, params: params)
to:
params = { story_id: @story.id, character: { story_id: @story.id, name: "Billy" } }
post(story_characters_path(params))
[EDIT]: This isn't quite correct, as Max pointed out above. His solution is the correct one
Upvotes: 0