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?
CodePudding user response:
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))
CodePudding user response:
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 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.