【问题标题】:Rspec no route matches polymorphicRspec没有路由匹配多态
【发布时间】:2018-03-04 03:56:47
【问题描述】:

我正在尝试测试我的多态 cmets 创建操作,但在 rspec 中总是没有路由匹配错误。

class CommentsController < ApplicationController
  before_action :authenticate_user!

  def create
    @comment = @commentable.comments.new(comment_params)
    @comment.user_id = current_user.id
    @comment.save
    redirect_to :back, notice: "Your comment was successfully posted."
  end

  private
  def comment_params
    params.require(:comment).permit(:body)
  end
end

Rspec

describe "POST #create" do
    context "with valid attributes" do
      before do
        @project = FactoryGirl.create(:project)
        @comment_attr = FactoryGirl.build(:comment).attributes
      end

      it "creates a new comment" do
        expect{
          post :create, params: { project_id: @project, comment: @comment_attr }
        }.to change(Comment, :count).by(1)
      end
    end
  end

我正在使用这种方法在我的另一个控制器中测试创建操作,并且一切都很好,但是由于某种原因,这里抛出了错误。我认为我的错误在于我将参数传递给发布创建操作但我没有看到错误。

更新

 resources :projects do
    resources :comments, module: :projects
    resources :tasks do
      resources :comments, module: :tasks
    end
  end

更新 2

失败/错误:发布:创建,参数:{ project_id:@project, 可评论:@project,评论:@comment_attr }

ActionController::UrlGenerationError: 没有路由匹配 {:action=>"create", :comment=>{"id"=>nil, "commentable_type"=>nil, "commentable_id"=>nil, "user_id"=>nil, "body"=>"MyText", "created_at"=>nil, "updated_at"=>nil, "attachment"=>nil}, :commentable=>#, :controller=>"cmets", :project_id=>#}

【问题讨论】:

  • 在你的控制器中设置@commentable是什么?除了您摘录的其余测试文件之外,查看routes.rb 也会有所帮助。
  • @JimVanFleet 用路线更新了我的问题。 Commentable 是项目或任务,但是当commentable 是项目时,我正在尝试测试用例。
  • 我理解您的意图,但根据我们上面看到的情况,@commentablenil。是ApplicationController的帮手吗?您的测试日志中是 404 还是 500?
  • 错误在哪里?为什么您会对错误有疑问而不发布错误?我了解基本错误,但发布了实际错误的一部分,因为“没有路线匹配错误”非常含糊。 No route matches {:controller =&gt; "comments", :action =&gt; "create"}No route matches {:controller =&gt; "unicorns", :action =&gt; "rainbows"}No route matches [POST] /projects/:project_id/comments 是一个非常不同的错误
  • @engineersmnky 我用完全错误更新了问题。

标签: ruby-on-rails ruby rspec rspec-rails


【解决方案1】:

我认为您的控制器命名空间与您定义的路由不匹配。控制器被定义为不嵌套(CommentsController),而相应的路由也嵌套在模块projects 内。嵌套路由不会影响 ActionDispatch 正在寻找的控制器。但是为路由定义一个模块将导致 Rails 期望模块命名空间内有一个控制器。在您的情况下,这将是 Projects::CommentsControllerTasks::CommentsController。详情请见"2.6 Controller Namespaces and Routing" of "Rails Routing from the Outside In"

我将您的路线添加到一个全新的 rails 项目并运行 rails routes。输出是:

                             Prefix Verb   URI Pattern                 Controller#Action
     project_comments GET    /projects/:project_id/comments(.:format)  projects/comments#index
                      POST   /projects/:project_id/comments(.:format)  projects/comments#create
                      ...

因此,您可以从路由中删除模块定义

resources :projects do
  resources :comments
  resources :tasks do
    resources :comments
  end
end

或将控制器嵌套在项目/任务命名空间中。鉴于您希望 cmets 具有多态性,我建议您使用第一个选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-27
    • 2019-05-25
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多