Rails - 测试控制器创建操作时没有路由匹配 "index"

Rails - No route matches "index" when testing controller create action

我有以下关系:

class Story < ApplicationRecord
  has_many :characters
end

class Character < ApplicationRecord
  belongs_to :story, required: true
end

以及以下路线:

# config/routes.rb
Rails.application.routes.draw do
  resources :stories do
    resources :characters
  end
end

最终看起来像这样:

在我的 CharactersController 测试中,我有:

test "can create a new character" do
  params = { story_id: @story.id, character: { name: "Billy" } }
  
  post(story_characters_path, params: params)

  # ... assertions follow
end

当谈到post(...)命令时,我收到:

DRb::DRbRemoteError: No route matches {:action=>"index", :controller=>"characters"}, missing required keys: [:story_id]

尽管 post,它似乎正在尝试索引操作而不是创建操作。有什么想法吗?

我想我明白了。我需要更改行:

params = { story_id: @story.id, character: { name: "Billy" } }
post(story_characters_path, params: params)

至:

params = { story_id: @story.id, character: { story_id: @story.id, name: "Billy" } }
post(story_characters_path(params))

[编辑]:正如 Max 在上面指出的那样,这不太正确。他的解决方案是正确的

调用嵌套 POST 或 PATCH 操作的正确方法是:

post story_characters_path(story_id: @story.id),
       params: { 
         character: { name: "Billy" }
       }

虽然 post(story_characters_path(params)) 可能有效,但您实际上是将参数放入查询字符串而不是请求正文中。

在大多数情况下,您实际上不会注意到任何差异,因为 Rails 将查询字符串参数与请求主体合并到 params 对象中,但它仍然可以让细微的错误溜走。

例如,如果它是一个 JSON 请求,您将无法在另一端获得正确的类型,因为查询字符串参数始终被视为字符串。