Simply Rails 2 Page 222 Undefined Method

Hello,

I’m using the highly recommended “Simply Rails 2” book with rails 3, so I’ve been running into problems here and there I’ve been able to work out for myself so far. But today I’ve hit a problem I can’t find help with…

On page 222, there’s a bit about adding some code to the webpage to show a “shove it!” button. The code that’s giving me a problem is the following in the app/views/stories/show.html.erb file:

<div id ="vote_form">
	<% form_remote_tag :url => story_votes_path(@story) do %>
		<%= submit_tag 'shove it' %>
	<% end %>
</div>

The error I’m getting is “undefined method `story_votes_path’ for #<#<Class:0x210fe6c>:0x210d93c>”

I’ve tried everything and I’m totally stuck. Thanks.

I solved my problem! Woo hoo!

The first change was using the book’s routes.rb as opposed to going with the change suggested to me by a different forum. My old routes.rb file was:

Shovell::Application.routes.draw do
  get "votes/create"

  resources :stories, :has_many => :votes
  get "stories/index"

So, I changed it to:

Shovell::Application.routes.draw do
  get "votes/create"

  #match ':controller(/:action(/:id(.:format)))'
  resources :stories, :has_many => :votes
  #map.resources :stories
  get "stories/index"

The next change is one that changed with Rails 3. It turns out form_remote_tag is no longer supported in Rails 3. The new thing to use is form_tag. The code needs to be as follows for Rails 3:

<div id="vote_form">
  <% form_tag :url => story_votes_path(@story), :remote => true do %>
    <%= submit_tag 'shove it' %>
  <% end %>
</div>

I hope this helps someone else someday!!

Hi there !

I’m currently facing the same problem as yourself, I haven’t fixed yet, even though you have placed the solution right there.

I think your solution isn’t completely Rails 3…

This code appears to be the Rails 2 way to do it…


Shovell::Application.routes.draw do
  get "votes/create"
 
  #match ':controller(/:action(/:id(.:format)))'
  resources :stories, :has_many => :votes
  #map.resources :stories
  get "stories/index"

To get the correct routes this code should be used instead in Rails 3

resources :stories do
		resources :votes
	end

that will actually give us the correct routes when using rake routes

stories_index GET /stories/index(.:format) {:controller=>“stories”, :action=>“index”}
votes_create GET /votes/create(.:format) {:controller=>“votes”, :action=>“create”}
story_votes GET /stories/:story_id/votes(.:format) {:action=>“index”, :controller=>“votes”}
POST /stories/:story_id/votes(.:format) {:action=>“create”, :controller=>“votes”}
new_story_vote GET /stories/:story_id/votes/new(.:format) {:action=>“new”, :controller=>“votes”}
edit_story_vote GET /stories/:story_id/votes/:id/edit(.:format) {:action=>“edit”, :controller=>“votes”}
story_vote GET /stories/:story_id/votes/:id(.:format) {:action=>“show”, :controller=>“votes”}
PUT /stories/:story_id/votes/:id(.:format) {:action=>“update”, :controller=>“votes”}
DELETE /stories/:story_id/votes/:id(.:format) {:action=>“destroy”, :controller=>“votes”}
stories GET /stories(.:format) {:action=>“index”, :controller=>“stories”}
POST /stories(.:format) {:action=>“create”, :controller=>“stories”}
new_story GET /stories/new(.:format) {:action=>“new”, :controller=>“stories”}
edit_story GET /stories/:id/edit(.:format) {:action=>“edit”, :controller=>“stories”}
story GET /stories/:id(.:format) {:action=>“show”, :controller=>“stories”}
PUT /stories/:id(.:format) {:action=>“update”, :controller=>“stories”}
DELETE /stories/:id(.:format) {:action=>“destroy”, :controller=>“stories”}

However this form syntax you suggested is still problematic to me:

<div id="vote_form">
  <% form_tag :url => story_votes_path(@story), :remote => true do %>
    <%= submit_tag 'shove it' %>
  <% end %>
</div>

When I click on the button for that Ajax Action it output the following error on the Browser:

No route matches “/stories/7-another-story”

Do you happen to know what could possibly be wrong ?

Please help me,

Best Regards,

Jose.

Jose,

I recently finished the “shovell” tutorial from “simply rails 2” while working with rails 3 also.

The fix to the problem regarding the ajax vote submission for me was to use the rails 2 way of doing things ‘form_remote_for’ with the plugin “Prototype Legacy Helper” (https://github.com/rails/prototype_legacy_helper). You might be able to get “remote => true do” to work with a bit of dabbling (I now have it working in several rails 3 projects, but at the time, I was happy to get it working even if it meant needing to use a plugin.)

Changes also had to be made to the path, and submit tag.


<div id="vote_form"> 
<%= form_remote_for [ @story, Vote.new ] do |f| %> 
<%= f.submit 'shove it' %> 
<% end %> 

It worked for me, it should work for you. Just remember to install the plugin , otherwise you’ll also have to dabble with trying to get the other remote call to work with frankly, other rails 2 ways of doing things.

Thank you Jon, and sorry for the duplicated thread, it’s just that the forum itself suggested that I post a new one.

Anyhow, I fixed this problem some time ago, hours after asking my question, and I did it 100% rails 3, without using any plug in, and using the latest route syntax as well.

Thanks anyway! I’ve posted a new question though, hope that you can take a look at it !

Once again thank you very much Sir !

Jose.

Can you post your solution? I am having the same problem and googling isn’t helping. Thanks!

Hi I assume you need the code for the form, right?

<div id="vote_form">
	<% form_tag story_votes_path(@story), :remote => true, :method => :post do %>
		<%= submit_tag "shove it" %>
	<% end %>
</div>

I had to research in the Rails API to get this done, but I think having the correct routes is even more important, as I said before the Rails 3 way for this exercise looks like the following:

resources :stories do
		resources :votes 
		get 'bin', :on => :collection
	end
	

	resource :session
	
	#This one goes at the end always !
	root :to => "stories#index"

This code above goes at the end of the routes.rb file, I recommend you have a look at…

Rails Routing from the Outside In

And don’t forget to delete the index.html file located at /public

Good luck, write back If you still got a question !

J

J, thanks so much for your quick reply and your help.

It looks like the only change I needed to make was to remove the “url =>” from the form_tag.

I’ll have to read up on how that works and when it should and shouldn’t be used.

Thanks again!

M