4

Here's how my routes look like:

 /article/:id/:action     {:root=>"article", :controller=>"article/article", :title=>"Article"}

Here's how my controller looks like:

# app/controllers/article/article_controller.rb
class ArticleController < ApplicationController
  def save_tags
    # code here
  end
end

I want to test the save_tags action so I write my spec like this:

describe ArticleController do       
   context 'saving tags' do
     post :save_tags, tag_id => 123, article_id => 1234
     # tests here
   end
end

But when I run this spec, I get the error

ActionController::RoutingError ...
No route matches {:controller=>"article/article", :action=>"save_tags"}

I think the issue is the save_tags action is a general controller action, ie. there's no /article/:id/save_tags in routes. What's the best way to test this controller action?

0

2 Answers 2

3

You're spot on. The issue is that you're looking for a route which doesn't have :id in it, but you don't have one. You'll need to pass a parameter to the post :save_tags of :id, and given the above question, I believe it is what you are calling article_id.

Therefore, try changing your test to:

describe ArticleController do       
   context 'saving tags' do
     post :save_tags, tag_id => 123, id => 1234
     # tests here
   end
end

Update

Rails might be getting confused because you're using :action in your route and I believe action is either a reserved word or a word that Rails treats as special. Maybe try changing your routes to:

/article/:id/:method_name {:root=>"article", :controller=>"article/article", :title=>"Article"}

And your test to:

describe ArticleController do       
  context 'saving tags' do
    post :save_tags, { :tag_id => 123, :article_id => 1234, :method_name => "save_tags" }
    # tests here
  end
end
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the response CDub. I tried your test above but I'm still getting the same error: No route matches {:tag_id=>123, :action=>"save_tags", :controller=>"article/article", :id=>1234}
I'd hesitate to have :action in your routes as Rails may get confused as to what that means in your route... Maybe try changing :action in your route to :method_name then pass in :method_name => "save_tags" in your test... I'll make an edit to show this.
0

You need a route to map to your controller actions

post '/article/:id/save_tags' 

should work, or consider using resources helper to build your routes

# creates the routes new, create, edit, update, show, destroy, index
resources :articles

# you can exclude any you do not want
resources :articles, except: [:destroy]

# add additional routes that require an article in the member block
resources :articles do 
  member do 
    post 'save_tags'
  end
end

# add additional routes that do NOT require an article in the collection block
resources :articles do 
  collection do 
    post 'publish_all'
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.