Route not generated, what have I missed?

Hey Guys,
I'm basing this off of the book Simply Rails 2 by Patrick Lenz.
I've got my word model:

# word.rb
has_many :votes

my vote mode;

# vote.rb
belongs_to :word, :counter_cache => true

my routes
# routes.rb
map.resources :words, :has_many => :votes

Then my problem. In my view I'm trying to use a generated url for a
form button to create a vote
# index.html.erb (in the words folder)
<% @words.each do |word| %>
    <td><%=h word.word %></td>
    <td><%=h word.user_id %></td>
    <td><%=h word.votes_count %></td>
    <td><%= link_to 'Show', word %></td>
    <td><%= link_to 'Destroy', word, :confirm => 'Are you
sure?', :method => :delete %></td>
    <div id="vote_form">
      <% form_tag :url => word_votes_path do %>
        <%= submit_tag 'shove it' %>
      <% end %>
<% end %>

word_votes_url failed to generate from
{:action=>"index", :controller=>"votes"} - you may have ambiguous
routes, or you may need to supply additional parameters for this
route. content_url has the following required parameters:
["words", :word_id, "votes"] - are they all satisfied?

I was under an impression having the has many and belongs to
relationships in the model, as well as the defined route would
generate the words_votes_path for me. It works in the book example and
I can't find any other defining attributes that I'm lacking but i must
be missing something.

I was so confident after I went through the multiple demos of rails.
But seem to be catching snags on much more then expected on my own

word_votes_url needs word id to generate the url, therefore
{:action=>"index", :controller=>"votes"} alone is not sufficient. You
need to pass word id as well.

See rake routes for all the paths/url generated and ids they need.


I don't know why but what you said just made it click for me.

I changed my form to:
      <% form_tag word_votes_path :word_id => do %>
        <%= submit_tag 'shove it' %>
      <% end %>

The votes get created and the counter_caches work like expected. The
only other thing i notice is the ugly action method it creates:
<form action="/word/votes?definition_id=2" method="post">

where as the simply rails demo produced:
<form action="/stories/6-a-fancy-new-story/votes" method="post"
onsubmit="new Ajax.Request('/stories/6-a-fancy-new-story/votes',
{asynchronous:true, evalScripts:true, parameters:Form.serialize
(this)}); return false;">

I realize the major difference is the use of form_remote_tag which
creates the ajax but thats not really the concern. Just the better
looking action url

In theory couldn't I get mine to look something like:

Thanks for the info so far.

Hi Brian,

You can modify your code like this as well:
            <% form_tag word_votes_path(word) do %> # note word as argument
              <%= submit_tag 'shove it' %>
            <% end %>

I am not aware of simply rails demo, but in general, word/2/votes
corresponds to index (get) or create (post) action, and it's not a
good idea to change the behaviour. You can add a new action in your
votes resource and call it something like say "count" and then submit
your remote form to this new "count" path.

See rails routing guide to understand more about routes, and how to
add new actions:


Create is exactly what the form goes to now which is why I don't get
why it hasn't created the word/2/votes route as create (post) is the
desired behavior. As well I've tried using word_votes_path(word) and I
actually receive this generated output:
<form action="/word/votes.%23%3Cword:0x2818ed4%3E" method="post">

** Just found my problem,
I was using map.resource :word, :has_many => :votes
but needed: map.resources :words, :has_many => :votes

it now generates the correct desired url. words/1/votes

Thanks for your help Abhinav !