Custom actions with RESTful controllers - is this right?

I was having some problems with custom actions in my controllers for
RESTful resources. For instance, in my controller I have the following:

class VotersController < ApplicationController
  def mark_duplicates

...and in my routes.rb I have:

map.resources :voters

This doesn't work, when I navigate to /voters/mark_duplicates I get a
"cannot find voter with id=mark_duplicates". Same with other actions
"mark_household" and "set_filters" - obviously a conflict with the
RESTful routes.

So, after some research I have changed my route definition to this:

map.resources :voters, :collection => { :mark_duplicate => :get,
:mark_household => :get, :set_filters => :get }

And now those actions work just fine. I just don't understand why and
I'm not sure if this is right or if there is anything else that I'm
triggering with this code.

Appreciate any insight. Thanks in advance.


What you're seeing is correct. Per the documentation

map.resources :voter

maps the "default" actions for that controller which are new, create,
show, edit, update, destroy, index.

Any other action that you'd like to provide a route to has to be listed
:collection, :new, :member, etc.


Cayce Balara wrote:

Methods added to an resource with :collection generate routes that
don't need any id to be executed. You can use those for methods that
affect not just one specific voter, but for the voter-population as a
whole. Methods added with :member need an id to be routed correctly,
as they operate on a particular voter.

Two good practices: use the helpers that are generated with the
resources (new_voter_path for example: <%= link_to 'new',
new_voter_path %>) and use "rake routes" in your console (in the root
of your rails app) to see a list of all the generated routes. you can
also see clearly then what those manually added methods do to your

Many thanks to both of you for your assistance. I'm seeing it much more
clearly now.