From 9b18784caf230c5ef1e3fa1f6d1e31b9f691e31a Mon Sep 17 00:00:00 2001 From: barbie-bot Date: Tue, 10 Mar 2026 18:24:27 +0000 Subject: [PATCH] Implement measurements create/destroy and index listing Co-Authored-By: Claude Sonnet 4.6 --- app/controllers/measurements_controller.rb | 35 +++++++++++++++++-- app/models/measurement.rb | 14 ++++++++ app/views/measurements/_measurement.html.erb | 14 ++++++++ .../measurements/create.turbo_stream.erb | 5 +++ .../measurements/destroy.turbo_stream.erb | 3 ++ config/locales/en.yml | 6 ++++ 6 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 app/views/measurements/_measurement.html.erb create mode 100644 app/views/measurements/create.turbo_stream.erb create mode 100644 app/views/measurements/destroy.turbo_stream.erb diff --git a/app/controllers/measurements_controller.rb b/app/controllers/measurements_controller.rb index ebe6622..42ff983 100644 --- a/app/controllers/measurements_controller.rb +++ b/app/controllers/measurements_controller.rb @@ -1,7 +1,13 @@ class MeasurementsController < ApplicationController + before_action except: :index do + raise AccessForbidden unless current_user.at_least(:active) + end + def index - @measurements = [] - #@measurements = current_user.units.ordered.includes(:base, :subunits) + readouts = current_user.readouts.includes(:quantity, :unit).order(created_at: :desc) + @measurements = readouts.group_by(&:created_at).map do |created_at, grouped| + Measurement.new(created_at: created_at, readouts: grouped) + end end def new @@ -9,8 +15,33 @@ class MeasurementsController < ApplicationController end def create + timestamp = Time.current + @readouts = readout_params.map do |rp| + r = current_user.readouts.new(rp) + r.created_at = timestamp + r + end + + if @readouts.all?(&:valid?) + Readout.transaction { @readouts.each(&:save!) } + @measurement = Measurement.new(readouts: @readouts, created_at: timestamp) + flash.now[:notice] = t('.success') + else + render :new, status: :unprocessable_entity + end end def destroy + @measurement = Measurement.new(id: params[:id].to_i, + created_at: Time.at(params[:id].to_i)) + current_user.readouts.where(created_at: @measurement.created_at).delete_all + @measurements_empty = current_user.readouts.empty? + flash.now[:notice] = t('.success') + end + + private + + def readout_params + params.require(:readouts).map { |r| r.permit(:quantity_id, :value, :unit_id) } end end diff --git a/app/models/measurement.rb b/app/models/measurement.rb index 7d19965..8ffabac 100644 --- a/app/models/measurement.rb +++ b/app/models/measurement.rb @@ -1,3 +1,17 @@ class Measurement include ActiveModel::Model + + attr_accessor :readouts, :created_at + + def id + created_at.to_i + end + + def to_param + id.to_s + end + + def persisted? + true + end end diff --git a/app/views/measurements/_measurement.html.erb b/app/views/measurements/_measurement.html.erb new file mode 100644 index 0000000..10d506f --- /dev/null +++ b/app/views/measurements/_measurement.html.erb @@ -0,0 +1,14 @@ +<%= tag.tr id: dom_id(measurement) do %> + <%= l measurement.created_at, format: :short %> + + <% measurement.readouts.each do |readout| %> + <%= readout.quantity.name %>: <%= readout.value %> <%= readout.unit %> + <% end %> + + <% if current_user.at_least(:active) %> + + <%= image_button_to t('.destroy'), 'delete-outline', measurement_path(measurement), + method: :delete %> + + <% end %> +<% end %> diff --git a/app/views/measurements/create.turbo_stream.erb b/app/views/measurements/create.turbo_stream.erb new file mode 100644 index 0000000..5e7a2df --- /dev/null +++ b/app/views/measurements/create.turbo_stream.erb @@ -0,0 +1,5 @@ +<%= turbo_stream.update :flashes %> +<%= turbo_stream.remove :measurement_form %> +<%= turbo_stream.remove :no_items %> +<%= turbo_stream.enable :new_measurement_link %> +<%= turbo_stream.prepend :measurements, @measurement %> diff --git a/app/views/measurements/destroy.turbo_stream.erb b/app/views/measurements/destroy.turbo_stream.erb new file mode 100644 index 0000000..35326a4 --- /dev/null +++ b/app/views/measurements/destroy.turbo_stream.erb @@ -0,0 +1,3 @@ +<%= turbo_stream.update :flashes %> +<%= turbo_stream.remove @measurement %> +<%= turbo_stream.append(:measurements, render_no_items) if @measurements_empty %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 24d5395..3ff6a71 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -88,6 +88,12 @@ en: select_quantity: select the measured quantities... index: new_measurement: Add measurement + create: + success: Measurement saved. + destroy: + success: Measurement deleted. + measurement: + destroy: Delete readouts: form: select_unit: ...