Commit e9413fd
Changed files (9)
app
models
views
workouts
config
initializers
spec
features
models
app/models/progress.rb
@@ -15,6 +15,10 @@ class Progress
end
def sets
- workout.sets.work.where(exercise: exercise).order(:created_at)
+ workout.sets.work.for(exercise).in_order
+ end
+
+ def status
+ "#{to_sets.join("/")} @ #{max_weight} lbs"
end
end
app/models/workout.rb
@@ -18,22 +18,29 @@ class Workout < ApplicationRecord
end
def train(exercise, target_weight, repetitions:, set: nil)
- set =
- if set.present? && sets.for(exercise).at(set).present?
- sets.for(exercise).at(set)
- else
- recommendation = program.recommendation_for(user, exercise)
- sets.build(
- type: WorkSet.name,
- exercise: exercise,
- target_repetitions: recommendation.repetitions
- )
- end
- set.update!(actual_repetitions: repetitions, target_weight: target_weight)
- set
+ all_sets = sets.for(exercise).to_a
+ if set.present? && (exercise_set = all_sets.to_a.at(set)).present?
+ exercise_set.update!(actual_repetitions: repetitions, target_weight: target_weight)
+ exercise_set
+ else
+ recommendation = program.recommendation_for(user, exercise)
+ exercise_set = sets.build(
+ type: WorkSet.name,
+ exercise: exercise,
+ target_repetitions: recommendation.repetitions
+ )
+ exercise_set.update!(actual_repetitions: repetitions, target_weight: target_weight)
+ exercise_set
+ end
end
def progress_for(exercise)
Progress.new(self, exercise)
end
+
+ def each_exercise
+ exercises.order(:created_at).distinct.each do |exercise|
+ yield exercise
+ end
+ end
end
app/views/workouts/index.html.erb
@@ -17,11 +17,10 @@
</p>
</a>
<div id="panel-<%= workout.id %>" class="content">
- <% workout.exercises.order(:created_at).uniq.each do |exercise| %>
- <% progress = workout.progress_for(exercise) %>
+ <% workout.each_exercise do |exercise| %>
<p class="text-center">
<strong><%= exercise.name %></strong>
- <%= progress.to_sets.join("/") %> @ <%= progress.max_weight %> lbs
+ <%= workout.progress_for(exercise).status %>
</p>
<% end %>
</div>
config/initializers/extensions.rb
@@ -15,9 +15,3 @@ class NilClass
0.0.lbs.to(units)
end
end
-
-class ActiveRecord::AssociationRelation
- def at(index)
- to_a.at(index)
- end
-end
spec/features/workouts_spec.rb
@@ -59,19 +59,19 @@ feature "Workouts", type: :feature do
end
it "saves the successful set" do
- first_squat_set = workout.sets.for(squat).at(0)
+ first_squat_set = workout.sets.for(squat).to_a.at(0)
subject.complete(set: first_squat_set)
expect(first_squat_set.reload.actual_repetitions).to eql(5)
end
it "saves the failed set" do
- second_squat_set = workout.sets.for(squat).at(1)
+ second_squat_set = workout.sets.for(squat).to_a.at(1)
subject.complete(set: second_squat_set, repetitions: 4)
expect(second_squat_set.reload.actual_repetitions).to eql(4)
end
it "does not change an incomplete set" do
- third_squat_set = workout.sets.for(squat).at(2)
+ third_squat_set = workout.sets.for(squat).to_a.at(2)
expect(third_squat_set.reload.actual_repetitions).to be_nil
end
end
spec/models/csv/import_spec.rb
@@ -76,18 +76,19 @@ describe Csv::Import do
subject.import_from(directory)
workout = user.workouts.order(:occurred_at).first
- row_session = workout.progress_for(barbell_row)
- expect(row_session.to_sets).to eql([5, 5, 5, 5, 5])
- expect(row_session.sets.at(0).target_weight).to eql(65.0)
- expect(row_session.sets.at(0).actual_repetitions).to eql(5)
- expect(row_session.sets.at(1).target_weight).to eql(65.0)
- expect(row_session.sets.at(1).actual_repetitions).to eql(5)
- expect(row_session.sets.at(2).target_weight).to eql(65.0)
- expect(row_session.sets.at(2).actual_repetitions).to eql(5)
- expect(row_session.sets.at(3).target_weight).to eql(65.0)
- expect(row_session.sets.at(3).actual_repetitions).to eql(5)
- expect(row_session.sets.at(4).target_weight).to eql(65.0)
- expect(row_session.sets.at(4).actual_repetitions).to eql(5)
+ progress = workout.progress_for(barbell_row)
+ expect(progress.to_sets).to eql([5, 5, 5, 5, 5])
+ sets = progress.sets.to_a
+ expect(sets.at(0).target_weight).to eql(65.0)
+ expect(sets.at(0).actual_repetitions).to eql(5)
+ expect(sets.at(1).target_weight).to eql(65.0)
+ expect(sets.at(1).actual_repetitions).to eql(5)
+ expect(sets.at(2).target_weight).to eql(65.0)
+ expect(sets.at(2).actual_repetitions).to eql(5)
+ expect(sets.at(3).target_weight).to eql(65.0)
+ expect(sets.at(3).actual_repetitions).to eql(5)
+ expect(sets.at(4).target_weight).to eql(65.0)
+ expect(sets.at(4).actual_repetitions).to eql(5)
end
it "excludes items that have already been imported" do
@@ -116,15 +117,16 @@ describe Csv::Import do
progress = workout.progress_for(chinups)
expect(progress).to_not be_nil
expect(progress.to_sets).to eql([5, 3, 2])
- expect(progress.sets.at(0).target_weight).to eql(0.0)
- expect(progress.sets.at(0).target_repetitions).to eql(5)
- expect(progress.sets.at(0).actual_repetitions).to eql(5)
- expect(progress.sets.at(1).target_weight).to eql(0.0)
- expect(progress.sets.at(1).target_repetitions).to eql(5)
- expect(progress.sets.at(1).actual_repetitions).to eql(3)
- expect(progress.sets.at(2).target_weight).to eql(0.0)
- expect(progress.sets.at(2).target_repetitions).to eql(5)
- expect(progress.sets.at(2).actual_repetitions).to eql(2)
+ sets = progress.sets.to_a
+ expect(sets.at(0).target_weight).to eql(0.0)
+ expect(sets.at(0).target_repetitions).to eql(5)
+ expect(sets.at(0).actual_repetitions).to eql(5)
+ expect(sets.at(1).target_weight).to eql(0.0)
+ expect(sets.at(1).target_repetitions).to eql(5)
+ expect(sets.at(1).actual_repetitions).to eql(3)
+ expect(sets.at(2).target_weight).to eql(0.0)
+ expect(sets.at(2).target_repetitions).to eql(5)
+ expect(sets.at(2).actual_repetitions).to eql(2)
end
it "imports the correct number of sets" do
@@ -132,11 +134,13 @@ describe Csv::Import do
subject.import(row)
workout = user.workouts.first
- expect(workout.progress_for(squat).sets.count).to eql(3)
- expect(workout.progress_for(squat).to_sets).to eql([5, 5, 5])
+ progress = workout.progress_for(squat)
+ expect(progress.sets.count).to eql(3)
+ expect(progress.to_sets).to eql([5, 5, 5])
- expect(workout.progress_for(deadlift).sets.count).to eql(1)
- expect(workout.progress_for(deadlift).to_sets).to eql([5])
+ progress = workout.progress_for(deadlift)
+ expect(progress.sets.count).to eql(1)
+ expect(progress.to_sets).to eql([5])
end
end
end
spec/models/exercise_set_spec.rb
@@ -14,4 +14,20 @@ describe ExerciseSet do
expect(subject.weight_per_side).to eql("25.0 lb/side")
end
end
+
+ describe ".for" do
+ let(:squat) { create(:exercise) }
+ let(:dip) { create(:exercise) }
+
+ it "returns all sets for the exercise only" do
+ squat_set = create(:work_set, exercise: squat)
+ dip_set = create(:work_set, exercise: dip)
+
+ expect(ExerciseSet.for(squat)).to match_array([squat_set])
+ end
+
+ it "returns nil" do
+ expect(ExerciseSet.for(squat)).to be_empty
+ end
+ end
end
spec/models/workout_spec.rb
@@ -32,12 +32,13 @@ describe Workout, type: :model do
expect(result).to be_persisted
expect(result.exercise).to eql(squat)
expect(subject.progress_for(squat).to_sets).to eql([5, 3])
- set = subject.sets.in_order.at(0)
+ sets = subject.sets.in_order.to_a
+ set = sets.at(0)
expect(set.exercise).to eql(squat)
expect(set.target_weight).to eql(target_weight.to_f)
expect(set.target_repetitions).to eql(5)
expect(set.actual_repetitions).to eql(5)
- set = subject.sets.in_order.at(1)
+ set = sets.at(1)
expect(set.exercise).to eql(squat)
expect(set.target_weight).to eql(target_weight.to_f)
expect(set.target_repetitions).to eql(5)
@@ -56,18 +57,19 @@ describe Workout, type: :model do
expect(result.exercise).to eql(squat)
progress = subject.progress_for(squat)
expect(progress.to_sets).to eql([5, 3, 5])
- expect(progress.sets.at(0).exercise).to eql(squat)
- expect(progress.sets.at(0).target_weight).to eql(target_weight.to_f)
- expect(progress.sets.at(0).target_repetitions).to eql(5)
- expect(progress.sets.at(0).actual_repetitions).to eql(5)
- expect(progress.sets.at(1).exercise).to eql(squat)
- expect(progress.sets.at(1).target_weight).to eql(new_weight.to_f)
- expect(progress.sets.at(1).target_repetitions).to eql(5)
- expect(progress.sets.at(1).actual_repetitions).to eql(3)
- expect(progress.sets.at(2).exercise).to eql(squat)
- expect(progress.sets.at(2).target_weight).to eql(target_weight.to_f)
- expect(progress.sets.at(2).target_repetitions).to eql(5)
- expect(progress.sets.at(2).actual_repetitions).to eql(5)
+ sets = progress.sets.to_a
+ expect(sets.at(0).exercise).to eql(squat)
+ expect(sets.at(0).target_weight).to eql(target_weight.to_f)
+ expect(sets.at(0).target_repetitions).to eql(5)
+ expect(sets.at(0).actual_repetitions).to eql(5)
+ expect(sets.at(1).exercise).to eql(squat)
+ expect(sets.at(1).target_weight).to eql(new_weight.to_f)
+ expect(sets.at(1).target_repetitions).to eql(5)
+ expect(sets.at(1).actual_repetitions).to eql(3)
+ expect(sets.at(2).exercise).to eql(squat)
+ expect(sets.at(2).target_weight).to eql(target_weight.to_f)
+ expect(sets.at(2).target_repetitions).to eql(5)
+ expect(sets.at(2).actual_repetitions).to eql(5)
end
it "cannot save a duplicate exercise" do
spec/factories.rb
@@ -7,6 +7,7 @@ FactoryGirl.define do
association :workout
target_repetitions { rand(12) }
target_weight { rand(400) }
+ factory :work_set, class: 'WorkSet'
end
factory :program do
name { FFaker::Internet.user_name }