Extra conversion options
This commit is contained in:
parent
a86c5afae2
commit
dd493a09d5
@ -1,6 +1,6 @@
|
|||||||
class RecipesController < ApplicationController
|
class RecipesController < ApplicationController
|
||||||
|
|
||||||
before_action :set_recipe, only: [:show, :edit, :update, :destroy, :scale]
|
before_action :set_recipe, only: [:show, :edit, :update, :destroy]
|
||||||
|
|
||||||
before_filter :ensure_valid_user, except: [:show, :scale, :index]
|
before_filter :ensure_valid_user, except: [:show, :scale, :index]
|
||||||
|
|
||||||
@ -12,6 +12,31 @@ class RecipesController < ApplicationController
|
|||||||
# GET /recipes/1
|
# GET /recipes/1
|
||||||
# GET /recipes/1.json
|
# GET /recipes/1.json
|
||||||
def show
|
def show
|
||||||
|
if params[:scale].present?
|
||||||
|
@scale = params[:scale]
|
||||||
|
@recipe.scale(params[:scale], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:system].present?
|
||||||
|
@system = params[:system]
|
||||||
|
case @system
|
||||||
|
when 'metric'
|
||||||
|
@recipe.convert_to_metric
|
||||||
|
when 'standard'
|
||||||
|
@recipe.convert_to_standard
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:unit].present?
|
||||||
|
@unit = params[:unit]
|
||||||
|
case @unit
|
||||||
|
when 'mass'
|
||||||
|
@recipe.convert_to_mass
|
||||||
|
when 'volume'
|
||||||
|
@recipe.convert_to_volume
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /recipes/1
|
# GET /recipes/1
|
||||||
|
@ -30,6 +30,30 @@ class Recipe < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def convert_to_metric
|
||||||
|
recipe_ingredients.each do |ri|
|
||||||
|
ri.to_metric
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_to_standard
|
||||||
|
recipe_ingredients.each do |ri|
|
||||||
|
ri.to_standard
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_to_mass
|
||||||
|
recipe_ingredients.each do |ri|
|
||||||
|
ri.to_mass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_to_volume
|
||||||
|
recipe_ingredients.each do |ri|
|
||||||
|
ri.to_volume
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def nutrition_data(recalculate = false)
|
def nutrition_data(recalculate = false)
|
||||||
if recalculate || @nutrition_data.nil?
|
if recalculate || @nutrition_data.nil?
|
||||||
@nutrition_data = calculate_nutrition_data
|
@nutrition_data = calculate_nutrition_data
|
||||||
|
@ -34,6 +34,52 @@ class RecipeIngredient < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_metric
|
||||||
|
return unless self.quantity.present?
|
||||||
|
value_unit = UnitConversion.parse(self.quantity, self.units)
|
||||||
|
value_unit = value_unit.to_metric
|
||||||
|
|
||||||
|
self.quantity = value_unit.pretty_value
|
||||||
|
self.units = value_unit.unit.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_standard
|
||||||
|
return unless self.quantity.present?
|
||||||
|
value_unit = UnitConversion.parse(self.quantity, self.units)
|
||||||
|
value_unit = value_unit.to_standard
|
||||||
|
|
||||||
|
self.quantity = value_unit.pretty_value
|
||||||
|
self.units = value_unit.unit.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_volume
|
||||||
|
return unless self.quantity.present?
|
||||||
|
if ingredient && ingredient.density
|
||||||
|
density = UnitConversion.parse(ingredient.density)
|
||||||
|
if density.density?
|
||||||
|
value_unit = UnitConversion.parse(self.quantity, self.units)
|
||||||
|
value_unit = value_unit.to_volume(density)
|
||||||
|
|
||||||
|
self.quantity = value_unit.pretty_value
|
||||||
|
self.units = value_unit.unit.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_mass
|
||||||
|
return unless self.quantity.present?
|
||||||
|
if ingredient && ingredient.density
|
||||||
|
density = UnitConversion.parse(ingredient.density)
|
||||||
|
if density.density?
|
||||||
|
value_unit = UnitConversion.parse(self.quantity, self.units)
|
||||||
|
value_unit = value_unit.to_mass(density)
|
||||||
|
|
||||||
|
self.quantity = value_unit.pretty_value
|
||||||
|
self.units = value_unit.unit.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def can_convert_to_grams?
|
def can_convert_to_grams?
|
||||||
if self.quantity.present? && self.units.present?
|
if self.quantity.present? && self.units.present?
|
||||||
value_unit = UnitConversion.parse(self.quantity, self.units)
|
value_unit = UnitConversion.parse(self.quantity, self.units)
|
||||||
|
@ -46,19 +46,9 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<h3 class="panel-title col-xs-7">Ingredients</h3>
|
<h3 class="panel-title col-xs-7">Ingredients</h3>
|
||||||
<div class="dropdown col-xs-5">
|
<div class="dropdown col-xs-5">
|
||||||
<button id="scaleLabel" type="button" class="pull-right btn btn-xs btn-default" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button id="scaleLabel" type="button" class="pull-right btn btn-xs btn-default" data-toggle="modal" data-target="#translate_modal">
|
||||||
Scale
|
Translate
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="scaleLabel">
|
|
||||||
<% ['1/4', '1/3', '1/2', '2/3', '3/4', '1', '1 1/2', '2', '3', '4'].each do |scale| %>
|
|
||||||
<% if scale == '1' %>
|
|
||||||
<li><%= link_to scale, @recipe %></li>
|
|
||||||
<% else %>
|
|
||||||
<li><%= link_to scale, scale_recipe_path(@recipe, scale) %></li>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -152,4 +142,79 @@
|
|||||||
<%= link_to 'Back', recipes_path, class: 'btn btn-default' %>
|
<%= link_to 'Back', recipes_path, class: 'btn btn-default' %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="translate_modal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title">Recipe Translation</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<%= form_tag(recipe_path(@recipe), method: :get, authenticity_token: false, enforce_utf8: false, id: 'translate_form') do %>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
|
||||||
|
<div class="form-group form-group">
|
||||||
|
<%= label_tag :scale, 'Scale', class: "control-label" %>
|
||||||
|
<%= select_tag :scale, options_for_select(['1/4', '1/3', '1/2', '2/3', '3/4', '1', '1 1/2', '2', '3', '4'], '1'), class: 'form-control' %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="well">
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="system" id="system_none" value="" checked>
|
||||||
|
No System Translation
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="system" id="system_standard" value="standard">
|
||||||
|
Convert to Standard Units
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="system" id="system_metric" value="metric">
|
||||||
|
Convert to Metric Units
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="well">
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="unit" id="unit_none" value="" checked>
|
||||||
|
No Unit Translation
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="unit" id="unit_mass" value="mass">
|
||||||
|
Convert to Mass Units
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="unit" id="unit_volume" value="volume">
|
||||||
|
Convert to Volume Units
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" class="btn btn-primary" form="translate_form">Convert</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,9 +1,7 @@
|
|||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
|
|
||||||
resources :recipes do
|
resources :recipes do
|
||||||
member do
|
|
||||||
get 'scale/:factor', action: :scale, as: :scale
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :ingredients, except: [:show] do
|
resources :ingredients, except: [:show] do
|
||||||
|
@ -80,4 +80,64 @@ module UnitConversion
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class MetricUnitConversion < Conversion
|
||||||
|
def convert(value_unit)
|
||||||
|
if value_unit.unit && !value_unit.unit.metric?
|
||||||
|
if value_unit.mass?
|
||||||
|
value_unit = value_unit.convert('g').auto_unit
|
||||||
|
elsif value_unit.volume?
|
||||||
|
value_unit = value_unit.convert('ml').auto_unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
value_unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class StandardUnitConversion < Conversion
|
||||||
|
def convert(value_unit)
|
||||||
|
if value_unit.unit && value_unit.unit.metric?
|
||||||
|
if value_unit.mass?
|
||||||
|
value_unit = value_unit.convert('oz').auto_unit
|
||||||
|
elsif value_unit.volume?
|
||||||
|
value_unit = value_unit.convert('cup').auto_unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
value_unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class VolumeUnitConversion < Conversion
|
||||||
|
def initialize(density_unit_value)
|
||||||
|
raise UnknownUnitError, "#{density_unit_value} is not a density" if !density_unit_value.density?
|
||||||
|
@density = density_unit_value
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert(value_unit)
|
||||||
|
if value_unit.mass?
|
||||||
|
unit = value_unit.unit.metric? ? 'ml' : 'cup'
|
||||||
|
value_unit.convert(unit, @density).auto_unit
|
||||||
|
else
|
||||||
|
value_unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class MassUnitConversion < Conversion
|
||||||
|
def initialize(density_unit_value)
|
||||||
|
raise UnknownUnitError, "#{density_unit_value} is not a density" if !density_unit_value.density?
|
||||||
|
@density = density_unit_value
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert(value_unit)
|
||||||
|
if value_unit.volume?
|
||||||
|
unit = value_unit.unit.metric? ? 'g' : 'oz'
|
||||||
|
value_unit.convert(unit, @density).auto_unit
|
||||||
|
else
|
||||||
|
value_unit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -4,6 +4,10 @@ module UnitConversion
|
|||||||
def self.for(value_string, unit_string = nil, formatter = nil)
|
def self.for(value_string, unit_string = nil, formatter = nil)
|
||||||
raise UnparseableUnitError, "value is empty" if value_string.blank?
|
raise UnparseableUnitError, "value is empty" if value_string.blank?
|
||||||
|
|
||||||
|
if ValueUnit === value_string
|
||||||
|
return value_string
|
||||||
|
end
|
||||||
|
|
||||||
if String === value_string && unit_string.nil?
|
if String === value_string && unit_string.nil?
|
||||||
value_string, unit_string = parse_single_string(value_string)
|
value_string, unit_string = parse_single_string(value_string)
|
||||||
end
|
end
|
||||||
@ -97,6 +101,24 @@ module UnitConversion
|
|||||||
AutoUnitConversion.new.convert(self)
|
AutoUnitConversion.new.convert(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_metric
|
||||||
|
MetricUnitConversion.new.convert(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_standard
|
||||||
|
StandardUnitConversion.new.convert(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_mass(density)
|
||||||
|
parsed_density = ValueUnit.for(density)
|
||||||
|
MassUnitConversion.new(parsed_density).convert(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_volume(density)
|
||||||
|
parsed_density = ValueUnit.for(density)
|
||||||
|
VolumeUnitConversion.new(parsed_density).convert(self)
|
||||||
|
end
|
||||||
|
|
||||||
def density?
|
def density?
|
||||||
unit.density?
|
unit.density?
|
||||||
end
|
end
|
||||||
|
@ -26,6 +26,16 @@ RSpec.describe UnitConversion::Conversion do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe UnitConversion::MetricUnitConversion do
|
||||||
|
it 'converts standard units' do
|
||||||
|
expect(UnitConversion::MetricUnitConversion.new.convert(get_value_unit(1, 'cup')).unit.to_s).to eq 'milliliter'
|
||||||
|
expect(UnitConversion::MetricUnitConversion.new.convert(get_value_unit(1, 'cup')).pretty_value).to eq '236.588'
|
||||||
|
|
||||||
|
expect(UnitConversion::MetricUnitConversion.new.convert(get_value_unit(1, 'gallon')).unit.to_s).to eq 'liter'
|
||||||
|
expect(UnitConversion::MetricUnitConversion.new.convert(get_value_unit(1, 'gallon')).pretty_value).to eq '3.785'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe UnitConversion::ConvertConversion do
|
describe UnitConversion::ConvertConversion do
|
||||||
it 'converts standard units' do
|
it 'converts standard units' do
|
||||||
expect(UnitConversion::ConvertConversion.new(get_unit('tbsp')).convert(get_value_unit(1, 'cups')).raw_value).to eq 16
|
expect(UnitConversion::ConvertConversion.new(get_unit('tbsp')).convert(get_value_unit(1, 'cups')).raw_value).to eq 16
|
||||||
|
Loading…
Reference in New Issue
Block a user