【问题标题】:Rails - No route matches "index" when testing controller create actionRails - 测试控制器创建操作时没有路由匹配“索引”
【发布时间】:2021-10-31 12:49:16
【问题描述】:

我有以下关系:

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=&gt;"index", :controller=&gt;"characters"}, missing required keys: [:story_id]

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

【问题讨论】:

    标签: ruby-on-rails ruby testing minitest


    【解决方案1】:

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

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

    虽然post(story_characters_path(params)) 可能会起作用,但您实际上是将参数放入查询字符串而不是请求正文中它们应该在的位置。

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

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

    【讨论】:

    • 谢谢,你是 100% 正确的。我的解决方案不正确 :) 谢谢!
    【解决方案2】:

    我想我明白了。我需要换行:

    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 上面指出的那样,这并不完全正确。他的解决方案是正确的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      相关资源
      最近更新 更多