From ea308a1e4a5f24a4b75d8eda8ef7a9c3a24e3ac4 Mon Sep 17 00:00:00 2001 From: cryptogopher Date: Sun, 21 Feb 2021 11:33:30 +0100 Subject: [PATCH] WIP: targets forms --- app/controllers/targets_controller.rb | 44 ++++++++++++++------------- app/models/quantity_value.rb | 2 +- app/models/target.rb | 3 +- app/models/threshold.rb | 2 ++ app/views/targets/_new_form.html.erb | 5 ++- config/routes.rb | 3 +- test/system/targets_test.rb | 6 ++-- 7 files changed, 34 insertions(+), 31 deletions(-) diff --git a/app/controllers/targets_controller.rb b/app/controllers/targets_controller.rb index b418dc0..261fea9 100644 --- a/app/controllers/targets_controller.rb +++ b/app/controllers/targets_controller.rb @@ -27,28 +27,24 @@ class TargetsController < ApplicationController end def create - @goal = @project.goals.find(params[:goal_id]) if params[:goal_id].present? - @goal ||= @project.goals.new - @goal.attributes = goal_params unless @goal.is_binding? - - @targets = @goal.targets.build(targets_params[:targets]) do |target| + @goal = @project.goals.find_by(id: params[:goal][:id]) || @project.goals.new + @goal.attributes = goal_params + @targets = @goal.targets.build(targets_params[:targets_attributes]) do |target| target.effective_from = params[:target][:effective_from] end + if @goal.target_exposures.empty? - @goal.quantities << @targets.map { |t| t.thresholds.first.quantity }.first(6) + @goal.quantities << @targets.map(&:quantity)[0..5] end # :save only after build, to re-display values in case records are invalid - if @goal.save && Target.transaction { @targets.all?(&:save) } + if @goal.save flash.now[:notice] = 'Created new target(s)' # create view should only refresh targets belonging to @goal # e.g. by rendering to div#goal-id-targets prepare_targets else - @targets.each do |target| - (target.thresholds.length...target.arity).each { target.thresholds.new } - target.thresholds[target.arity..-1].map(&:destroy) - end + @targets.each { |t| t.thresholds.new unless t.thresholds.present? } render :new end end @@ -90,22 +86,28 @@ class TargetsController < ApplicationController private def goal_params - params.require(:goal).permit(:name, :description) + params.require(:goal).permit( + :name, + :description + ) end def targets_params - params.require(:target).permit( - targets: [ - :id, - :condition, - :scope, - thresholds_attributes: [ + params.require(:goal).permit( + targets_attributes: + [ :id, :quantity_id, - :value, - :unit_id + :scope, + :destroy, + thresholds_attributes: [ + :id, + :quantity_id, + :value, + :unit_id, + :_destroy + ] ] - ] ) end diff --git a/app/models/quantity_value.rb b/app/models/quantity_value.rb index ca1c740..74bdb14 100644 --- a/app/models/quantity_value.rb +++ b/app/models/quantity_value.rb @@ -5,7 +5,7 @@ class QuantityValue < ActiveRecord::Base # to allow for accessing registry item without knowing QuantityValue (subitem) # type, e.g. qv.registry.completed_at belongs_to :registry, polymorphic: true - belongs_to :quantity, required: true + belongs_to :quantity, -> { where(domain: DOMAIN) }, required: true belongs_to :unit, required: true # Uniqueness is checked exclusively on the other end of association level. diff --git a/app/models/target.rb b/app/models/target.rb index 0091539..11fbdb7 100644 --- a/app/models/target.rb +++ b/app/models/target.rb @@ -1,6 +1,7 @@ class Target < ActiveRecord::Base belongs_to :goal, inverse_of: :targets, required: true - belongs_to :quantity, inverse_of: :targets, required: true + belongs_to :quantity, -> { where.not(domain: :target) }, inverse_of: :targets, + required: true belongs_to :item, polymorphic: true, inverse_of: :targets has_many :thresholds, -> { joins(:quantity).order(:lft) }, as: :registry, inverse_of: :target, dependent: :destroy, validate: true diff --git a/app/models/threshold.rb b/app/models/threshold.rb index 742da1e..54984c6 100644 --- a/app/models/threshold.rb +++ b/app/models/threshold.rb @@ -1,4 +1,6 @@ class Threshold < QuantityValue + DOMAIN = :target + # Need to specify polymorphic association so :registry_type gets written (see # QuantityValue for explanation why it's needed) belongs_to :target, inverse_of: :thresholds, polymorphic: true, required: true, diff --git a/app/views/targets/_new_form.html.erb b/app/views/targets/_new_form.html.erb index 4bab8be..932c4a0 100644 --- a/app/views/targets/_new_form.html.erb +++ b/app/views/targets/_new_form.html.erb @@ -1,8 +1,7 @@

<%= t ".heading_new_target" %>

-<%= labelled_form_for @goal, - url: project_targets_path(@project, @view_params), - remote: true, +<%# url: project_targets_path(@project, @view_params), %> +<%= labelled_form_for [@project, @goal], remote: true, html: {id: 'new-target-form', name: 'new-target-form'} do |goal_f| %> <%= render partial: 'targets/form', locals: {goal_f: goal_f} %> diff --git a/config/routes.rb b/config/routes.rb index 28b9be6..5e12b07 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,11 +12,10 @@ resources :projects, shallow: true do post 'toggle_exposure', controller: :targets end end - resources :targets, except: [:show, :edit, :update] do + resources :targets, except: [:show, :edit] do collection do get 'edit/:date', action: :edit, as: :edit get 'subthresholds/(:parent_id)', action: :subthresholds, as: :subthresholds - patch :update post 'reapply/:date', action: :reapply, as: :reapply end end diff --git a/test/system/targets_test.rb b/test/system/targets_test.rb index c78b475..8023442 100644 --- a/test/system/targets_test.rb +++ b/test/system/targets_test.rb @@ -68,7 +68,7 @@ class TargetsTest < BodyTrackingSystemTestCase within 'form#new-target-form' do within 'p.target' do select quantities(:quantities_energy).name - select '==' + select quantities(:quantities_target_equal).name fill_in with: '1750' select units(:units_kcal).shortname end @@ -79,8 +79,8 @@ class TargetsTest < BodyTrackingSystemTestCase t = Target.last assert_equal @project1.goals.binding, t.goal assert_equal Date.current, t.effective_from - assert_equal quantities(:quantities_energy), t.thresholds.first.quantity - assert_equal '==', t.condition + assert_equal quantities(:quantities_energy), t.quantity + assert_equal quantities(:quantities_target_equal), t.thresholds.first.quantity assert_equal 1750, t.thresholds.first.value assert_equal units(:units_kcal), t.thresholds.first.unit