An error adding activities.

Subscribe to An error adding activities. 12 post(s), 4 voice(s)

 
Avatar mongo 8 post(s)

I’m about halfway through the Exercisr. I am at the point where I’m trying to add an activity to a workout. Everything seems to be fine until I attempt to Save the activity.

(Sorry, but I am using more current versions that what is prescribed in the book:
On Ubuntu linux, ruby 1.8.7, rails 2.3.2, and MySQL rather than SQLLite. So far these versions have not caused any problems.)

I get this error message:

Couldn't find Workout without an ID

from this application trace:

/home/phil/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:1572:in `find_from_ids'
/home/phil/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:616:in `find'
/home/phil/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/active_record/associations/association_collection.rb:60:in `find'
/home/phil/www/exercisr/app/controllers/activities_controller.rb:92:in `find_workout'

I’m a little confused as to where the workout_id comes from in the protected method find_workout in the activities_controller.

My model objects looks like this:

class Workout < ActiveRecord::Base
  belongs_to :user
  has_many :activities, :dependent => :destroy
  has_many :exercises, :through => :activities
  validates_presence_of :date
end

class Activity < ActiveRecord::Base
  belongs_to :exercise
  belongs_to :workout
  validates_presence_of :resistance, :repititions
  attr_accessor :new_exercise_name
  before_save :create_exercise_if_submitted

  def create_exercise_if_submitted
    create_exercise(:user_id => workout.user_id, :name => new_exercise_name) unless new_exercise_name.blank?
  end

end

(I know repetition is spelled incorrectly, but it is incorrect consistently within the application).

Can anyone point me in a direction where to look as to why the find_workout is not happening? Is it that I am somewhere somehow not passing a workout object to the activity controller?

 
Avatar EldonAlameda Administrator 216 post(s)

mongo,

if you want to zip up the application and email it to me, I’ll take a look at this weekend and let you know what the issues are.

—Eldon

 
Avatar mongo 8 post(s)

Eldon,

Thank you so much for taking the time to look at this, and the most helpful book. Tell your publisher there is an increasing demand for an updated version…

I have zipped up the exercisr directory and emailed it to an alameda eldon gmail account. I’m using mysql, so no db is included in the file.

Please don’t spend a whole lot of time looking at this, as me struggling to figure it out is all part of the learning experience. I do appreciate any tips or pointers in the general direction to look.

If I understand the concepts correctly, things like workout_id are automatically generated and set up based upon the relationships defined in the models of the related objects. In this case between an activity and a workout. I’m sure its something simple.

 
Avatar GruffDavies 7 post(s)

I’m having exactly the same problem. Any ideas?

Thanks

Gruff

 
Avatar GruffDavies 7 post(s)

I fixed it. The tutorial code is wrong in several places. If you run “rake routes” you can inspect the routes created and also the named path helpers. The code is specifying the wrong helpers in a few places.

1. In the the app/views/show.html.erb the :url should be HTH

Gruff

 
Avatar GruffDavies 7 post(s)

Sorry, my post got munged as I didn’t escape my code samples.

 
Avatar GruffDavies 7 post(s)

There are two file changes needed to get it to work.

1. change the _activity partial to look like:

<tr> 
  <td><%= activity.exercise.name %></td> 
  <td><%= activity.repetitions %></td> 
  <td><%= activity.resistance %></td> 
  <td><%=link_to image_tag("edit_photo.gif", {:title => "Edit Exercise"}), edit_workout_activity_path(@workout, activity) %></td> 
  <td><%= link_to image_tag("delete_photo.gif", {:title => "Delete Exercise"}), workout_activity_path(@workout, activity), 
                                                 :confirm => 'Are you sure?', 
                                                 :method => :delete %> </td> 
</tr> 

 
Avatar GruffDavies 7 post(s)

and change the workout show view to look like:

<h1><%= h @workout.label %> Workout on <%= h @workout.date.to_s(:long) %> </h1> 
<table>
   <tr><th>Exercise</th><th>Reps</th><th>Resistance</th></tr>
   <%= render :partial => 'activities/activity', :collection => @activities %> 
</table> 

<h3>Add Exercise to this Workout</h3> 
<% form_for(:activity, :url => workout_activities_path(@workout)) do |f| %>
   <%= render :partial => 'activities/form', :locals => {:f => f} %> 
<% end %> 

<%= link_to 'Back', workouts_path %>

 
Avatar GruffDavies 7 post(s)

I think you can also use a more concise method on config/routes.rb to map subordinate routes like this:

map.resources :workouts :has_many => :activities

instead of
map.resources :workouts do |workout|
  workout.resources :activities
end

 
Avatar GruffDavies 7 post(s)

No, it seems I lied about the routes thing. Read it somewhere, maybe it’s an edge rails thing.

 
Avatar EldonAlameda Administrator 216 post(s)

Crap – I got so swamped at work that I completely forgot about this problem. So my apologies to Mongo for not looking into this.

If GruffDavies is correct and it’s simply a matter of the named route helpers that are generated are incorrect that would make sense. This book was written using Rails 1.2.6, and there were some minor changes to those routes in the early 2.x days. One of which was the automatic pre-fixing of nested routes with the parent routes name.

And Gruff – yes you should be able to use the shorthand version of :has_many in route generation now as well (also added to Rails after the book was published). You can use the shortcut has_one to link to a singular nested resource and a has_many to link to a collection nested resource. (However – I will note that I rarely see this idiom used). As for why it wasn’t working for you – I think you’re missing a comma between :workouts and :has_many.

Hope that helps – once again sorry for forgetting about this.

 
Avatar alex 1 post

Hello. I am actually having this exact same problem. I’ve been looking at this error for 3 hours, and really, even though I’ve made some progress, I’m frankly at a loss.

I know this topic is about a year old… but can I still get some input?

The error is:

Couldn’t find Workout without an ID

and my routes looks like this:

bq.(ActionController::Routing::Routes.draw do |map| map.resources :activities

map.resources :workouts do |workout|
  workout.resources :activities
end
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
map.login '/login', :controller => 'sessions', :action => 'new'
map.register '/register', :controller => 'users', :action => 'create'
map.signup '/signup', :controller => 'users', :action => 'new'
map.resources :users
map.welcome '/welcome', :controller => 'sessions', :action => 'welcome'
map.resource :session
map.resources :exercises
  1. The priority is based upon order of creation: first created -> highest priority.
  1. Sample of regular route:
  2. map.connect ‘products/:id’, :controller => ‘catalog’, :action => ‘view’
  3. Keep in mind you can assign values other than :controller and :action
  1. Sample of named route:
  2. map.purchase ‘products/:id/purchase’, :controller => ‘catalog’, :action => ‘purchase’
  3. This route can be invoked with purchase_url(:id => product.id)
  1. Sample resource route (maps HTTP verbs to controller actions automatically):
  2. map.resources :products
  1. Sample resource route with options:
  2. map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
  1. Sample resource route with sub-resources:
  2. map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
  1. Sample resource route with more complex sub-resources
  2. map.resources :products do |products|
  3. products.resources :comments
  4. products.resources :sales, :collection => { :recent => :get }
  5. end
  1. Sample resource route within a namespace:
  2. map.namespace :admin do |admin|
  3. # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
  4. admin.resources :products
  5. end
  1. You can have the root of your site routed with map.root—just remember to delete public/index.html. map.root :controller => “sessions”, :action => ‘new’
  1. See how all your routes lay out with “rake routes”
  1. Install the default routes as the lowest priority.
  2. Note: These default routes make all actions in every controller accessible via GET requests. You should
  3. consider removing or commenting them out if you’re using named routes and resources. map.connect ’:controller/:action/:id’ map.connect ’:controller/:action/:id.:format’
    end
    )