Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7192597
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T19:58:23+00:00 2026-05-28T19:58:23+00:00

I have a Rails application (Rails 3.0.10) where users can have many articles, and

  • 0

I have a Rails application (Rails 3.0.10) where users can have many articles, and where the users can leave comments on the articles. Comments are made on the article show page.

Now I want to test the create action of the CommentsController, however, I have problems of invoking the post method with the right parameters.

Here’s the code of the CommentsController:

class CommentsController < ApplicationController

  # create a comment and bind it to an article and a user  
  def create
    @article = Article.find(params[:article_id])
    @user = User.find(@article.user_id)
    @comment = @article.comments.build(params[:comment])
    @comment.user_id = current_user.id

    commenters = [] 
    @article.comments.each {
      |comment|
      commenters << User.find(comment.user_id)
    }
    commenters.uniq!

    respond_to do |format|
      if @comment.save        

        #Notify user who offers article on new comment, else notify the commenters
        if @article.user_id != @comment.user_id
          UserMailer.new_article_comment_email(@user, @comment).deliver
        else        
          commenters.each {
            |commenter|
            UserMailer.new_article_comment_email(commenter, @comment).deliver
          }
        end

        format.html { 
          redirect_to(@article)
          flash[:notice] = t(:comment_create_success)
        }
      else
        format.html { 
          redirect_to(@article) 
          flash[:error] = t(:comment_create_error)
        }
      end
    end
  end
end

The RSpec code for testing this action (some experiments so far) is the following:

require 'spec_helper'
require 'ruby-debug'

describe CommentsController do
  render_views

  describe "POST 'create'" do

    before(:each) do
      @user = FactoryGirl.create(:user)

      @article = FactoryGirl.build(:article)
      @article.user_id = @user.id
      @article.save

      @article_attributes = FactoryGirl.attributes_for(:article)
      @comment_attributes = FactoryGirl.attributes_for(:comment)
    end

    it "should create a new comment" do
      expect {
        post :create, :comment => @comment_attributes
      }.to change(Comment, :count).by(1)
    end

    it "should create a new comment, redirect to the article show page of this comment and notify the user on successful saving of the comment" do
      post :create, :comment => @comment_attributes, :article_id => @article.id.to_s, :user_id => @user.id.to_s
      flash[:notice].should_not be_nil
      response.should redirect_to(article_path(@article))
    end

  end

end

Both tests fail, however, due to different reasons that I am unable to fix:

    Failures:

      1) CommentsController POST 'create' should create a new comment
         Failure/Error: post :create, :comment => @comment_attributes
         ActionController::RoutingError:
           No route matches {:comment=>{:body=>"This is the body text of a comment"}, :controller=>"comments", :action=>"create"}
         # ./spec/controllers/comments_controller_spec.rb:22:in `block (4 levels) in <top (required)>'
         # ./spec/controllers/comments_controller_spec.rb:21:in `block (3 levels) in <top (required)>'

      2) CommentsController POST 'create' should create a new comment, redirect to the article show page of this comment and notify the user on successful saving of the comment
         Failure/Error: post :create, :comment => @comment_attributes, :article_id => @article.id.to_s, :user_id => @user.id.to_s
         RuntimeError:
           Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
         # ./app/controllers/comments_controller.rb:8:in `create'
         # ./spec/controllers/comments_controller_spec.rb:27:in `block (3 levels) in <top (required)>'

I would be great if someone could help me out. Thanks in advance!

Update: Here’s the routes.rb I am using:

Cinderella::Application.routes.draw do

  # The priority is based upon order of creation:
  # first created -> highest priority.

  # Sample of regular route:
  #   match 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action

  # Sample of named route:
  #   match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)  

  match '/signup',  :to => 'users#new'
  match '/signin',  :to => 'sessions#new'
  match '/signout',  :to => 'sessions#destroy'

  match '/home', :to => 'pages#home'
  match '/about',   :to => 'pages#about'
  match '/faq', :to => 'pages#faq'
  match '/howitworks_sellers', :to => "pages#howitworks_sellers"
  match '/howitworks_buyers', :to => "pages#howitworks_buyers"
  match '/contact', :to => 'pages#contact'

  match '/articles/:id/ratings', :to => 'ratings#destroy'

  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  resources :articles do
    resources :comments, :only => [:create, :destroy]
  end

  resources :ratings
  resources :ratings do
    collection do
      post 'destroy'
    end
  end

  resources :users do
    resources :articles
  end

  resources :sessions, :only => [:new, :create, :destroy]

  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', :on => :collection
  #     end
  #   end

  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  root :to => "pages#home"

  # See how all your routes lay out with "rake routes"

  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
  # match ':controller(/:action(/:id(.:format)))'
end
#== Route Map
# Generated on 14 Dec 2011 14:24
#
#            signin        /signin(.:format)                           {:controller=>"sessions", :action=>"new"}
#           signout        /signout(.:format)                          {:controller=>"sessions", :action=>"destroy"}
#              home        /home(.:format)                             {:controller=>"pages", :action=>"home"}
#             about        /about(.:format)                            {:controller=>"pages", :action=>"about"}
#               faq        /faq(.:format)                              {:controller=>"pages", :action=>"faq"}
#          articles GET    /articles(.:format)                         {:action=>"index", :controller=>"articles"}
#                   POST   /articles(.:format)                         {:action=>"create", :controller=>"articles"}
#       new_article GET    /articles/new(.:format)                     {:action=>"new", :controller=>"articles"}
#      edit_article GET    /articles/:id/edit(.:format)                {:action=>"edit", :controller=>"articles"}
#           article GET    /articles/:id(.:format)                     {:action=>"show", :controller=>"articles"}
#                   PUT    /articles/:id(.:format)                     {:action=>"update", :controller=>"articles"}
#                   DELETE /articles/:id(.:format)                     {:action=>"destroy", :controller=>"articles"}
#     user_articles GET    /users/:user_id/articles(.:format)          {:action=>"index", :controller=>"articles"}
#                   POST   /users/:user_id/articles(.:format)          {:action=>"create", :controller=>"articles"}
#  new_user_article GET    /users/:user_id/articles/new(.:format)      {:action=>"new", :controller=>"articles"}
# edit_user_article GET    /users/:user_id/articles/:id/edit(.:format) {:action=>"edit", :controller=>"articles"}
#      user_article GET    /users/:user_id/articles/:id(.:format)      {:action=>"show", :controller=>"articles"}
#                   PUT    /users/:user_id/articles/:id(.:format)      {:action=>"update", :controller=>"articles"}
#                   DELETE /users/:user_id/articles/:id(.:format)      {:action=>"destroy", :controller=>"articles"}
#             users GET    /users(.:format)                            {:action=>"index", :controller=>"users"}
#                   POST   /users(.:format)                            {:action=>"create", :controller=>"users"}
#          new_user GET    /users/new(.:format)                        {:action=>"new", :controller=>"users"}
#         edit_user GET    /users/:id/edit(.:format)                   {:action=>"edit", :controller=>"users"}
#              user GET    /users/:id(.:format)                        {:action=>"show", :controller=>"users"}
#                   PUT    /users/:id(.:format)                        {:action=>"update", :controller=>"users"}
#                   DELETE /users/:id(.:format)                        {:action=>"destroy", :controller=>"users"}
#          sessions POST   /sessions(.:format)                         {:action=>"create", :controller=>"sessions"}
#       new_session GET    /sessions/new(.:format)                     {:action=>"new", :controller=>"sessions"}
#           session DELETE /sessions/:id(.:format)                     {:action=>"destroy", :controller=>"sessions"}
#              root        /(.:format)                                 {:controller=>"pages", :action=>"home"}

Update: Here’s the modification I did according to nmotts suggestions:

require 'spec_helper'
require 'ruby-debug'

describe CommentsController do
  render_views

  describe "POST 'create'" do

    before(:each) do
      @user = FactoryGirl.create(:user)

      @article = FactoryGirl.build(:article)
      @article.user_id = @user.id
      @article.save

      @comment_attributes = FactoryGirl.attributes_for(:comment, :article_id => @article)
    end

    it "should create a new comment" do
      post :create, :article_id => @article.id.to_s, :comment => @comment_attributes
    end

  end

end

And the FactoryGirl definition for comment:

factory :comment do
  body "This is the body text of a comment"
  article
end

Unfortunately, the code is not yet working.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T19:58:24+00:00Added an answer on May 28, 2026 at 7:58 pm

    For a nested resource you need to construct the setup data and the post in such a way as to identify the parent article when posting the child comment.

    One approach is to setup Factory Girl associations correctly and then ensure the parent element is set when creating the child attributes. It would look something like this:

    In the comment factory:

    FactoryGirl.define do
      Factory :comment do
        comment "My comment"
        article
      end
    end
    

    By calling article, and making sure that there is a valid factory called :article then FactoryGirl will create an article when a comment is created. To make the tests flow well we should actually be specific about which article is used when the comment is created, so now that the Factory is in place we use the following in the spec.

    @comment_attributes = FactoryGirl.attributes_for(:comment, :article_id => @article)
    

    This will build comment attributes which are automatically attached to @article. The final piece is then to construct the post, making sure that we include the parent and the child.

    When a nested resource is posted it expects params for both the parent resource and the child. In rspec we can provide this in the post as follows:

    post :create, :article_id => @article, :comment => @comment_attributes
    

    This should link up all the pieces correctly.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a rails application what I want to send my users notifications when
I'm using devise in my rails 3.2 application. I have a users/new page where
I'm using rails 3, and began my application with ActiveRecord. Now, I have many
I have a Rails application which I now plan to deploy many instances to
I have a rails application that has three different types of users and I
I have a really simple Rails application that allows users to register their attendance
I have made a simple Rails application that allows people to comment on posts.
I have a Ruby on Rails application that allows for users to create a
I created a Ruby on Rails application (2.3.9) where users can record workouts. I
I have a (rails 3) application that allows users to query for books. I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.