Commit e310031

mo khan <mo@mokhan.ca>
2016-06-04 22:00:20
implement controller actions to record a new workout.
1 parent 603056c
app/controllers/training_sessions_controller.rb
@@ -11,6 +11,35 @@ class TrainingSessionsController < ApplicationController
   end
 
   def new
+    @workout = current_user.next_workout
+  end
+
+  def create
+    secure_params = params.require(:training_session).permit(:workout_id, :body_weight)
+    workout = Workout.find(secure_params[:workout_id])
+    @training_session = current_user.begin_workout(
+      workout,
+      DateTime.now,
+      secure_params[:body_weight]
+    )
+    render nothing: true
+  end
+
+  def edit
+    @training_session = current_user.training_sessions.find(params[:id])
+  end
+
+  def update
+    secure_params = params.
+      require(:training_session).
+      permit(:exercise_id, :weight, sets: [])
+    training_session = current_user.training_sessions.find(params[:id])
+    training_session.train(
+      Exercise.find(secure_params[:exercise_id]),
+      secure_params[:weight],
+      secure_params[:sets]
+    )
+    render nothing: true
   end
 
   def upload
app/models/program.rb
@@ -16,6 +16,10 @@ class Program < ActiveRecord::Base
     end
   end
 
+  def next_workout_after(workout)
+    workouts.where.not(name: workout.name).first
+  end
+
   class << self
     def stronglifts
       Program.find_by(name: STRONG_LIFTS)
app/models/user.rb
@@ -72,6 +72,22 @@ class User < ActiveRecord::Base
     end
   end
 
+  def last_workout
+    if training_sessions.any?
+      training_sessions.order(:occurred_at).last.workout
+    else
+      current_program.workouts.order(name: :desc).first
+    end
+  end
+
+  def next_workout
+    last_workout.next_workout
+  end
+
+  def current_program
+    Program.stronglifts
+  end
+
   def google_drive
     GoogleDrive.new(self)
   end
app/models/workout.rb
@@ -22,4 +22,8 @@ class Workout < ActiveRecord::Base
       repetitions: repetitions
     ) unless exercises.include?(exercise)
   end
+
+  def next_workout
+    program.next_workout_after(self)
+  end
 end
app/views/training_sessions/edit.html.erb
config/routes.rb
@@ -2,7 +2,7 @@ Rails.application.routes.draw do
   root "sessions#new"
   resources :sessions, only: [:new, :create, :destroy]
   resources :registrations, only: [:new, :create]
-  resources :training_sessions, only: [:index, :new] do
+  resources :training_sessions, only: [:index, :new, :create, :edit, :update] do
     collection do
       post :upload
       post :drive_upload
spec/controllers/training_sessions_controller_spec.rb
@@ -85,4 +85,63 @@ describe TrainingSessionsController do
       expect(flash[:notice]).to eql(success_message)
     end
   end
+
+  describe "#new" do
+    include_context "stronglifts_program"
+
+    it "loads the next workout in the program" do
+      create(:training_session, user: user, workout: workout_a)
+
+      get :new
+
+      expect(assigns(:workout)).to eql(workout_b)
+    end
+
+    it "loads the first workout in the program" do
+      get :new
+
+      expect(assigns(:workout)).to eql(workout_a)
+    end
+  end
+
+  describe "#create" do
+    include_context "stronglifts_program"
+    let(:body_weight) { rand(250.0) }
+
+    it "creates a new training session" do
+      post :create, training_session: {
+        workout_id: workout_b.id,
+        body_weight: body_weight
+      }
+      expect(response.status).to eql(200)
+      expect(user.reload.training_sessions.count).to eql(1)
+      expect(user.last_workout).to eql(workout_b)
+      expect(user.training_sessions.last.body_weight).to eql(body_weight.to_f)
+    end
+  end
+
+  describe "#edit" do
+    let(:training_session) { create(:training_session, user: user) }
+
+    it "loads the training session" do
+      get :edit, id: training_session.id
+      expect(assigns(:training_session)).to eql(training_session)
+    end
+  end
+
+  describe "#update" do
+    include_context "stronglifts_program"
+    let(:training_session) { create(:training_session, user: user, workout: workout_a) }
+
+    it "records the exercise" do
+      patch :update, id: training_session.id, training_session: {
+        exercise_id: squat.id,
+        weight: 315,
+        sets: [5, 5, 5],
+      }
+      expect(training_session.exercises).to include(squat)
+      expect(training_session.progress_for(squat).target_weight).to eql(315.to_f)
+      expect(training_session.progress_for(squat).sets).to eql(['5', '5', '5'])
+    end
+  end
 end