1
0

Adding MeasurementRoutine selection/editing support

This commit is contained in:
cryptogopher 2020-04-02 02:23:53 +02:00
parent 0c724ed63f
commit 9f63c14f8a
15 changed files with 94 additions and 21 deletions

View File

@ -10,7 +10,8 @@ module Concerns::Finders
def find_measurement def find_measurement
@measurement = Measurement.find(params[:id]) @measurement = Measurement.find(params[:id])
@project = @measurement.routine.project @routine = @measurement.routine
@project = @routine.project
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
render_404 render_404
end end
@ -22,15 +23,22 @@ module Concerns::Finders
render_404 render_404
end end
def find_quantity(id = :id) def find_measurement_routine(id = params[:id])
@quantity = Quantity.find(params[id]) @routine = MeasurementRoutine.find(id)
@project = @routine.project
rescue ActiveRecord::RecordNotFound
render_404
end
def find_quantity(id = params[:id])
@quantity = Quantity.find(id)
@project = @quantity.project @project = @quantity.project
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
render_404 render_404
end end
def find_quantity_by_quantity_id def find_quantity_by_quantity_id
find_quantity(:quantity_id) find_quantity(params[:quantity_id])
end end
def find_unit def find_unit

View File

@ -23,6 +23,7 @@ class IngredientsController < ApplicationController
def new def new
@ingredient = @project.ingredients.new @ingredient = @project.ingredients.new
# passing attr for Nutrient after_initialize # passing attr for Nutrient after_initialize
# FIXME: is this necessary when creating through association?
@ingredient.nutrients.new(ingredient: @ingredient) @ingredient.nutrients.new(ingredient: @ingredient)
end end

View File

@ -0,0 +1,12 @@
class MeasurementRoutinesController < ApplicationController
include Concerns::Finders
before_action :find_measurement_routine, only: [:show, :edit]
before_action :authorize
def show
end
def edit
end
end

View File

@ -18,16 +18,25 @@ class MeasurementsController < ApplicationController
def new def new
@measurement = @project.measurements.new @measurement = @project.measurements.new
@measurement.build_routine @routine = @measurement.build_routine
@measurement.readouts.new @measurement.readouts.new
end end
def create def create
@measurement = @project.measurements.new(measurement_params) # Nested attributes cannot create outer object (Measurement) and at the same time edit
# existing nested object (MeasurementRoutine) if it's not associated with outer object
# https://stackoverflow.com/questions/6346134/
# That's why routine needs to be found and associated before measurement initialization
@measurement = @project.measurements.new do |m|
routine_id = params[:measurement][:routine_attributes][:id]
m.routine = @project.measurement_routines.find_by(id: routine_id) if routine_id
end
@measurement.attributes = measurement_params
@measurement.routine.project = @project @measurement.routine.project = @project
@routine = @measurement.routine
if @measurement.save if @measurement.save
if @measurement.routine.columns.empty? if @routine.columns.empty?
@measurement.routine.quantities << @measurement.readouts.map(&:quantity).first(6) @routine.quantities << @measurement.readouts.map(&:quantity).first(6)
end end
flash[:notice] = 'Created new measurement' flash[:notice] = 'Created new measurement'
@ -93,6 +102,7 @@ class MeasurementsController < ApplicationController
:source_id, :source_id,
routine_attributes: routine_attributes:
[ [
:id,
:name, :name,
:description :description
], ],
@ -118,7 +128,7 @@ class MeasurementsController < ApplicationController
end end
def prepare_readouts def prepare_readouts
@quantities = @measurement.routine.quantities.includes(:formula) @quantities = @routine.quantities.includes(:formula)
@measurements, @requested_r, @extra_r, @formula_q = @routine.measurements @measurements, @requested_r, @extra_r, @formula_q = @routine.measurements
.includes(:routine, :source) .includes(:routine, :source)
.filter(session[:m_filters], @quantities) .filter(session[:m_filters], @quantities)

View File

@ -0,0 +1,2 @@
module MeasurementRoutinesHelper
end

View File

@ -5,6 +5,7 @@ class Measurement < ActiveRecord::Base
attrs['name'].blank? attrs['name'].blank?
} }
after_destroy { self.routine.destroy if self.routine.measurements.empty? } after_destroy { self.routine.destroy if self.routine.measurements.empty? }
has_one :project, through: :routine
belongs_to :source, required: false belongs_to :source, required: false

View File

@ -0,0 +1,7 @@
<div class="tabular">
<%= fields_for 'measurement[routine_attributes]', @routine do |ff| %>
<%= ff.hidden_field :id %>
<p><%= ff.text_field :name, required: true, style: "width: 95%;" %></p>
<p><%= ff.text_area :description, cols: 40, rows: 3, style: "width: 95%;" %></p>
<% end %>
</div>

View File

@ -0,0 +1,3 @@
<% unless @routine.description.empty? %>
<p><%= @routine.description %></p>
<% end %>

View File

@ -0,0 +1,27 @@
<div>
<%= f.fields_for :routine do |ff| %>
<p>
<%= ff.select :id,
options_from_collection_for_select(@project.measurement_routines,
:id, :name, @routine.id),
{label: :field_measurement_routine, required: true},
onchange: "var mr_id = $('#measurement_routine_attributes_id option:selected').val();
$.ajax({
url: '#{measurement_routine_path(id: :mr_id)}'.replace('mr_id', mr_id),
dataType: 'script'
});
return false;" %>
<%= link_to l(:button_edit), '#',
onclick: "var mr_id = $('#measurement_routine_attributes_id option:selected').val();
$.ajax({
url: '#{edit_measurement_routine_path(id: :mr_id)}'.replace('mr_id', mr_id),
dataType: 'script'
});
return false;",
class: 'icon icon-edit' %>
</p>
<% end %>
<div id='measurement-routine'>
<%= render partial: 'measurement_routines/show' %>
</div>
</div>

View File

@ -0,0 +1 @@
$('#measurement-routine-form').html('<%= j render partial: 'measurement_routines/form' %>');

View File

@ -0,0 +1 @@
$('#measurement-routine').html('<%= j render partial: 'measurement_routines/show' %>');

View File

@ -1,17 +1,14 @@
<%= error_messages_for @measurement %> <%= error_messages_for @measurement %>
<fieldset class="box"> <div class="box">
<legend ><%= t('.label_routine') %></legend> <div id='measurement-routine-form' class="tabular">
<div class="tabular"> <% if @routine.persisted? %>
<%= f.fields_for :routine do |ff| %> <%= render partial: 'measurement_routines/show_form', locals: {f: f} %>
<p><%= ff.text_field :name, required: true, style: "width: 95%;" %></p> <% else %>
<p><%= ff.text_area :description, cols: 40, rows: 3, style: "width: 95%;" %></p> <%= render partial: 'measurement_routines/form', locals: {f: f} %>
<% end %> <% end %>
</div> </div>
</fieldset> <hr style="width: 95%;">
<fieldset class="box">
<legend ><%= t('.label_measurement') %></legend>
<div class="tabular"> <div class="tabular">
<p><%= f.select :source_id, source_options, <p><%= f.select :source_id, source_options,
{required: false, include_blank: t('.null_source')} %></p> {required: false, include_blank: t('.null_source')} %></p>
@ -42,7 +39,7 @@
onclick: 'newReadout(); return false;' %> onclick: 'newReadout(); return false;' %>
</p> </p>
</div> </div>
</fieldset> </div>
<%= javascript_tag do %> <%= javascript_tag do %>
function newReadout() { function newReadout() {

View File

@ -1,6 +1,7 @@
# English strings go here for Rails i18n # English strings go here for Rails i18n
en: en:
body_trackers_menu_caption: 'Body trackers' body_trackers_menu_caption: 'Body trackers'
field_measurement_routine: 'Routine'
field_readouts: 'Readouts' field_readouts: 'Readouts'
field_taken_at_date: 'Taken at' field_taken_at_date: 'Taken at'
field_order: 'Order' field_order: 'Order'

View File

@ -7,7 +7,7 @@ resources :projects, shallow: true do
post 'defaults' post 'defaults'
end end
end end
resources :measurement_routines, only: [] do resources :measurement_routines, only: [:show, :edit] do
member do member do
get 'readouts', to: 'measurements#readouts' get 'readouts', to: 'measurements#readouts'
post 'toggle_column', to: 'measurements#toggle_column' post 'toggle_column', to: 'measurements#toggle_column'

View File

@ -13,6 +13,7 @@ Redmine::Plugin.register :body_tracking do
project_module :body_tracking do project_module :body_tracking do
permission :view_body_trackers, { permission :view_body_trackers, {
body_trackers: [:index], body_trackers: [:index],
measurement_routines: [:show],
measurements: [:index, :readouts, :filter], measurements: [:index, :readouts, :filter],
ingredients: [:index, :nutrients, :filter], ingredients: [:index, :nutrients, :filter],
sources: [:index], sources: [:index],
@ -21,6 +22,7 @@ Redmine::Plugin.register :body_tracking do
}, read: true }, read: true
permission :manage_common, { permission :manage_common, {
body_trackers: [:defaults], body_trackers: [:defaults],
measurement_routines: [:edit],
measurements: [:new, :create, :edit, :update, :destroy, :retake, :toggle_column], measurements: [:new, :create, :edit, :update, :destroy, :retake, :toggle_column],
ingredients: [:new, :create, :edit, :update, :destroy, :toggle, :toggle_column, ingredients: [:new, :create, :edit, :update, :destroy, :toggle, :toggle_column,
:import], :import],