Reputation: 183
I am trying to test my polymorphic comments create action but I always get no route matches error in 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
I am using this approach for testing create action in my another controllers and there is everything good, but here from some reason is throws error. I think my error is in line where I pass params to post create action but I do not see error.
UPDATE
resources :projects do
resources :comments, module: :projects
resources :tasks do
resources :comments, module: :tasks
end
end
UPDATE 2
Failure/Error: post :create, params: { project_id: @project, commentable: @project, comment: @comment_attr }
ActionController::UrlGenerationError: No route matches {: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=>"comments", :project_id=>#}
Upvotes: 0
Views: 187
Reputation: 2242
I think that your controller namespace does not match the routes you define. The controller is defined to not be nested (CommentsController
) whereas the corresponding routes are nested and inside a module projects
as well. Nesting the routes will have no influence on the controller ActionDispatch is looking for. But defining a module for the route will lead to rails expecting a controller inside the module namespace. In your case that would be Projects::CommentsController
and Tasks::CommentsController
. Please see "2.6 Controller Namespaces and Routing" of "Rails Routing from the Outside In" for further details.
I added your routes to a brand new rails project and ran rails routes
. The output is:
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
...
You can therefor either remove the module definition from your routes
resources :projects do
resources :comments
resources :tasks do
resources :comments
end
end
or nest the controllers inside in a project/task namespace. Given that you want polymorphism for your comments, I would advise using the first option.
Upvotes: 0