Route Generation error for :create action in Minitest

162 views Asked by At

I am currently writing functional tests for all of my controllers. For every single one, I can't get the create action to work. I keep getting the following error when I run rake test:

 ActionController::UrlGenerationError: No route matches {:action=>"create", :comment=>{:content=>"I'm a comment.", :product_id=>"685617403"}, :controller=>comments}

Here is the action I am trying to test:

class CommentsController < ApplicationController
  before_action :authenticate_user!
  def create
    @product =Product.find(params[:product_id])
    @comment=Comment.create(params[:comment].permit(:content))
    @comment.user_id= current_user.id
    @comment.product_id= @product.id
    if @comment.save
      redirect_to product_path(@product)
    else
      render 'new'
    end
  end
end

Here is the route:

POST     /products/:product_id/comments(.:format)          comments#create

The following is my test:

    def setup
    @user=users(:chris)
    @product=products(:banana)
  end

  test "should redirect destroy action if not signed in" do
    post :create, comment: { content: "I'm a comment.", product_id:@product.id}
    assert_redirected_to new_user_session_path
  end

I can't figure out what I am doing wrong. I am fairly certain I am passing the correct params in.I've also tried it with and without a user_id: param and it still throws the same error. It works fine on the app, I've called params in the web console when making the request and it matches what I am passing. The only thing I am missing is the :id but I assumed that would be assigned when the comment was created in the test. Also there are no unique constraints which would prevent the created comment from being valid. My associations are in place and when it works on the app it saves to the database with the user_id and product_id. What am I missing?

1

There are 1 answers

1
Topher Hunt On BEST ANSWER

I think you need to put product_id as its own first-level param too in order for the route to match up correctly. So try this instead:

post :create, product_id: @product.id, comment: { content: "I'm a comment.", product_id: @product.id }

Note that in your controller action, you reference params[:product_id] directly already, you don't reference params[:comment][:product_id]. Then, to reduce duplication, you can create the Comment as a child of that Product in your controller:

@comment = @product.comments.create(other params...)

Rails' routing errors can be extremely vague and unhelpful. 90% of the time the error boils down to some variation of this: a mismatched or misnamed ID, a nil value, etc.