updates
This commit is contained in:
parent
ffed63e0b3
commit
0c4c5b899b
@ -7,12 +7,19 @@ class CalculatorController < ApplicationController
|
||||
def calculate
|
||||
input = params[:input]
|
||||
output_unit = params[:output_unit]
|
||||
ingredient_id = params[:ingredient_id]
|
||||
ingredient = nil
|
||||
density = params[:density]
|
||||
density = nil unless density.present?
|
||||
|
||||
if ingredient_id.present?
|
||||
ingredient = Ingredient.find_by_ingredient_id(ingredient_id)
|
||||
end
|
||||
|
||||
data = {errors: [], output: ''}
|
||||
|
||||
begin
|
||||
UnitConversion::with_custom_units(ingredient ? ingredient.custom_units : []) do
|
||||
unit = UnitConversion.parse(input)
|
||||
if output_unit.present?
|
||||
unit = unit.convert(output_unit, density)
|
||||
@ -20,7 +27,7 @@ class CalculatorController < ApplicationController
|
||||
else
|
||||
data[:output] = unit.auto_unit.to_s
|
||||
end
|
||||
|
||||
end
|
||||
rescue UnitConversion::UnparseableUnitError => e
|
||||
data[:errors] << e.message
|
||||
end
|
||||
|
@ -61,12 +61,12 @@ class LogsController < ApplicationController
|
||||
private
|
||||
|
||||
def set_log
|
||||
@log = Log.includes({recipe: {recipe_ingredients: {ingredient: :ingredient_units} }}).find(params[:id])
|
||||
@log = Log.includes({recipe: {recipe_ingredients: {food: :food_units} }}).find(params[:id])
|
||||
end
|
||||
|
||||
def set_recipe
|
||||
if params[:recipe_id].present?
|
||||
@recipe = Recipe.includes([{recipe_ingredients: [:ingredient]}]).find(params[:recipe_id])
|
||||
@recipe = Recipe.includes([{recipe_ingredients: [:food]}]).find(params[:recipe_id])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -81,7 +81,7 @@ class RecipesController < ApplicationController
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_recipe
|
||||
@recipe = Recipe.includes(recipe_ingredients: {food: :food_units }).find(params[:id])
|
||||
@recipe = Recipe.includes(recipe_ingredients: [{food: :food_units }, {recipe_as_ingredient: {recipe_ingredients: {food: :food_units }}}]).find(params[:id])
|
||||
end
|
||||
|
||||
# Never trust parameters from the scary internet, only allow the white list through.
|
||||
|
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<span ref="wrapper" class="rating" @click="handleClick" @mousemove="handleMousemove" @mouseleave="handleMouseleave">
|
||||
<span class="set empty-set">
|
||||
<app-icon v-for="i in starCount" :key="i" icon="star-empty" padding="0"></app-icon>
|
||||
<app-iconic-icon v-for="i in starCount" :key="i" icon="star-empty" size="md"></app-iconic-icon>
|
||||
</span>
|
||||
<span class="set filled-set" :style="filledStyle">
|
||||
<app-icon v-for="i in starCount" :key="i" icon="star" padding="0"></app-icon>
|
||||
<app-iconic-icon v-for="i in starCount" :key="i" icon="star" size="md"></app-iconic-icon>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
@ -113,6 +113,11 @@
|
||||
|
||||
.set {
|
||||
white-space: nowrap;
|
||||
|
||||
svg.iconic {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-set {
|
||||
|
@ -10,10 +10,6 @@
|
||||
<div class="column">
|
||||
<app-text-field label="Source" v-model="recipe.source"></app-text-field>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-text-field label="Description" type="textarea" v-model="recipe.description"></app-text-field>
|
||||
|
@ -16,7 +16,8 @@
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<transition-group tag="tbody" name="list-item-move">
|
||||
<tr v-for="i in taskItems" :key="i.id" @click="toggleItem(i)">
|
||||
<td>
|
||||
<div class="check">
|
||||
@ -28,7 +29,9 @@
|
||||
<td>{{ i.quantity }}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr v-if="taskItems.length === 0">
|
||||
</transition-group>
|
||||
<tbody v-if="taskItems.length === 0">
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
No Items
|
||||
</td>
|
||||
@ -73,20 +76,16 @@
|
||||
},
|
||||
|
||||
computed: {
|
||||
completedTaskItems() {
|
||||
return (this.taskList ? this.taskList.task_items : []).filter(i => i.completed);
|
||||
},
|
||||
|
||||
uncompletedTaskItems() {
|
||||
return (this.taskList ? this.taskList.task_items : []).filter(i => !i.completed);
|
||||
},
|
||||
|
||||
taskItems() {
|
||||
const top = [];
|
||||
const bottom = [];
|
||||
const list = (this.taskList ? this.taskList.task_items : []);
|
||||
|
||||
for (let i of list) {
|
||||
if (!i.completed) {
|
||||
top.push(i);
|
||||
} else {
|
||||
bottom.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return top.concat(bottom);
|
||||
return this.uncompletedTaskItems.concat(this.completedTaskItems);
|
||||
}
|
||||
},
|
||||
|
||||
@ -148,8 +147,9 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.check .icon {
|
||||
div.check {
|
||||
border: 2px solid $link;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
</style>
|
@ -44,7 +44,7 @@
|
||||
<div class="field column">
|
||||
<label class="label">Density</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" placeholder="8.345 lb/gallon" v-model="density">
|
||||
<input class="input" type="text" placeholder="8.345 lb/gallon" v-model="density" :disabled="ingredient !== null">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -82,13 +82,13 @@
|
||||
},
|
||||
|
||||
searchItemSelected(ingredient) {
|
||||
this.ingredient = ingredient;
|
||||
this.ingredient_name = ingredient.name;
|
||||
this.density = ingredient.density;
|
||||
this.ingredient = ingredient || null;
|
||||
this.ingredient_name = ingredient.name || null;
|
||||
this.density = ingredient.density || null;
|
||||
},
|
||||
|
||||
updateOutput: debounce(function() {
|
||||
this.loadResource(api.getCalculate(this.input, this.outputUnit, this.density)
|
||||
this.loadResource(api.getCalculate(this.input, this.outputUnit, this.ingredient ? this.ingredient.ingredient_id : null, this.density)
|
||||
.then(data => {
|
||||
this.output = data.output;
|
||||
this.errors = data.errors;
|
||||
@ -108,7 +108,7 @@
|
||||
created() {
|
||||
this.$watch(
|
||||
function() {
|
||||
return this.input + this.outputUnit + this.density;
|
||||
return [this.input, this.outputUnit, this.density, this.ingredient];
|
||||
},
|
||||
function() {
|
||||
this.updateOutput();
|
||||
|
@ -16,9 +16,9 @@
|
||||
<div v-if="currentTaskList !== null">
|
||||
|
||||
<div class="box">
|
||||
<button class="button" @click="deleteCompletedItems">Clear Completed</button>
|
||||
<button class="button" @click="completeAllItems">Check All</button>
|
||||
<button class="button" @click="unCompleteAllItems">Uncheck All</button>
|
||||
<button class="button" @click="deleteCompletedItems" v-if="completedItemCount > 0">Clear Completed</button>
|
||||
<button class="button" @click="completeAllItems" v-if="uncompletedItemCount > 0">Check All</button>
|
||||
<button class="button" @click="unCompleteAllItems" v-if="completedItemCount > 0">Uncheck All</button>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
@ -66,6 +66,14 @@
|
||||
} else {
|
||||
return this.currentTaskList.name;
|
||||
}
|
||||
},
|
||||
|
||||
completedItemCount() {
|
||||
return this.currentTaskList === null ? 0 : this.currentTaskList.task_items.filter(i => i.completed).length;
|
||||
},
|
||||
|
||||
uncompletedItemCount() {
|
||||
return this.currentTaskList === null ? 0 : this.currentTaskList.task_items.filter(i => !i.completed).length;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -205,10 +205,11 @@ class Api {
|
||||
return this.get("/ingredients/search", params);
|
||||
}
|
||||
|
||||
getCalculate(input, output_unit, density) {
|
||||
getCalculate(input, output_unit, ingredient_id, density) {
|
||||
const params = {
|
||||
input,
|
||||
output_unit,
|
||||
ingredient_id,
|
||||
density
|
||||
};
|
||||
return this.get("/calculator/calculate", params);
|
||||
|
@ -15,7 +15,8 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
//.expand-enter,
|
||||
//.expand-leave-to {
|
||||
// height: 0;
|
||||
//}
|
||||
|
||||
|
||||
.list-item-move-move {
|
||||
transition: transform 0.25s;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
class Food < ApplicationRecord
|
||||
class Food < Ingredient
|
||||
include TokenizedLike
|
||||
|
||||
belongs_to :user
|
||||
@ -33,18 +33,10 @@ class Food < ApplicationRecord
|
||||
self
|
||||
end
|
||||
|
||||
def nutrition_errors
|
||||
[]
|
||||
end
|
||||
|
||||
def nutrition_unit
|
||||
UnitConversion.parse('100 grams')
|
||||
end
|
||||
|
||||
def density?
|
||||
!density.nil?
|
||||
end
|
||||
|
||||
def ndbn=(value)
|
||||
@usda_food = nil
|
||||
super
|
||||
|
41
app/models/ingredient.rb
Normal file
41
app/models/ingredient.rb
Normal file
@ -0,0 +1,41 @@
|
||||
class Ingredient < ApplicationRecord
|
||||
self.abstract_class = true
|
||||
|
||||
class << self
|
||||
|
||||
def find_by_ingredient_id(ingredient_id)
|
||||
puts "looking up |#{ingredient_id}|"
|
||||
case ingredient_id
|
||||
when /^R(\d+)$/
|
||||
puts 'rec'
|
||||
Recipe.find($1)
|
||||
when /^F(\d+)$/
|
||||
puts 'food'
|
||||
Food.find($1)
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def ingredient_id
|
||||
case self
|
||||
when Recipe
|
||||
"R#{id}"
|
||||
when Food
|
||||
"F#{id}"
|
||||
else
|
||||
raise 'Unknown ingredient'
|
||||
end
|
||||
end
|
||||
|
||||
def nutrition_errors
|
||||
[]
|
||||
end
|
||||
|
||||
def density?
|
||||
!self.density.nil?
|
||||
end
|
||||
|
||||
end
|
@ -50,7 +50,7 @@ class NutritionData
|
||||
end
|
||||
|
||||
unless i.ingredient.nutrition_errors.empty?
|
||||
@errors << "#{i.name} has errors: #{i.ingredient.nutrition_errors.join(", ")}"
|
||||
@errors << "#{i.name}: #{i.ingredient.nutrition_errors.join(", ")}"
|
||||
end
|
||||
|
||||
missing = []
|
||||
|
@ -1,4 +1,4 @@
|
||||
class Recipe < ApplicationRecord
|
||||
class Recipe < Ingredient
|
||||
include DefaultValues
|
||||
include TokenizedLike
|
||||
|
||||
@ -157,10 +157,6 @@ class Recipe < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def density?
|
||||
!density.nil?
|
||||
end
|
||||
|
||||
def custom_units
|
||||
arbitrary = self.yields_list.select { |y| !y.mass? && !y.volume? }
|
||||
mass = self.yields_list.select { |y| y.mass? }
|
||||
|
@ -1,15 +1,7 @@
|
||||
|
||||
json.array! @ingredients do |i|
|
||||
|
||||
json.extract! i, :name
|
||||
|
||||
case i
|
||||
when Recipe
|
||||
json.id "R#{i.id}"
|
||||
when Food
|
||||
json.id "F#{i.id}"
|
||||
else
|
||||
json.id nil
|
||||
end
|
||||
json.extract! i, :ingredient_id, :name, :density
|
||||
json.id i.ingredient_id
|
||||
|
||||
end
|
28
db/seeds.rb
28
db/seeds.rb
@ -12,7 +12,7 @@ puts "Seeding..."
|
||||
|
||||
dan = User.create!({username: 'dan', full_name: 'Dan', email: 'dan.elbert@gmail.com', password: 'qwerty', password_confirmation: 'qwerty'})
|
||||
|
||||
ingredients = {
|
||||
foods = {
|
||||
water: {name: 'Water', density: '1 g/ml'},
|
||||
butter: {name: 'Butter, Salted', ndbn: '01001'},
|
||||
butter_sal: {name: 'Butter, Unsalted', density: '226 gram/cup'},
|
||||
@ -43,8 +43,8 @@ ingredients = {
|
||||
|
||||
}
|
||||
|
||||
ingredients.each do |k, v|
|
||||
ingredients[k] = Food.create!({user_id: dan.id}.merge(v))
|
||||
foods.each do |k, v|
|
||||
foods[k] = Food.create!({user_id: dan.id}.merge(v))
|
||||
end
|
||||
|
||||
g = Recipe.create!({
|
||||
@ -69,19 +69,19 @@ bb = Recipe.create!({
|
||||
bb.tag_names = ['beef', 'dinner', 'stirfry']
|
||||
|
||||
[
|
||||
{quantity: '1', units: 'pound', preparation: 'flank steak, skirt steak, hanger steak, or flap meat, cut into 1/4-inch thick strips', food: ingredients[:flank]},
|
||||
{quantity: '1/4', units: 'cup', preparation: 'divided', food: ingredients[:soy_sauce]},
|
||||
{quantity: '1/4', units: 'cup', preparation: 'divided', food: ingredients[:shaoxing]},
|
||||
{quantity: '2', units: 'teaspoons', preparation: '', food: ingredients[:cornstarch]},
|
||||
{quantity: '1/3', units: 'cup', preparation: '', food: ingredients[:stock]},
|
||||
{quantity: '1/4', units: 'cup', preparation: '', food: ingredients[:oyster_sauce]},
|
||||
{quantity: '1', units: 'tablespoon', preparation: '', food: ingredients[:sugar]},
|
||||
{quantity: '1', units: 'teaspoon', preparation: '', food: ingredients[:seasame_oil]},
|
||||
{quantity: '2', units: 'medium cloves', preparation: 'finely minced', food: ingredients[:garlic]},
|
||||
{quantity: '1', units: 'pound', preparation: 'flank steak, skirt steak, hanger steak, or flap meat, cut into 1/4-inch thick strips', food: foods[:flank]},
|
||||
{quantity: '1/4', units: 'cup', preparation: 'divided', food: foods[:soy_sauce]},
|
||||
{quantity: '1/4', units: 'cup', preparation: 'divided', food: foods[:shaoxing]},
|
||||
{quantity: '2', units: 'teaspoons', preparation: '', food: foods[:cornstarch]},
|
||||
{quantity: '1/3', units: 'cup', preparation: '', food: foods[:stock]},
|
||||
{quantity: '1/4', units: 'cup', preparation: '', food: foods[:oyster_sauce]},
|
||||
{quantity: '1', units: 'tablespoon', preparation: '', food: foods[:sugar]},
|
||||
{quantity: '1', units: 'teaspoon', preparation: '', food: foods[:seasame_oil]},
|
||||
{quantity: '2', units: 'medium cloves', preparation: 'finely minced', food: foods[:garlic]},
|
||||
{quantity: '2', units: 'teaspoons', preparation: 'finely minced', name: 'ginger root'},
|
||||
{quantity: '3', units: '', preparation: 'whites finely sliced, greens cut into 1/2-inch segments, reserved separately', name: 'Scallions'},
|
||||
{quantity: '4', units: 'tablespoons', preparation: '', food: ingredients[:peanut_oil]},
|
||||
{quantity: '1', units: 'pound', preparation: '', food: ingredients[:broccoli]},
|
||||
{quantity: '4', units: 'tablespoons', preparation: '', food: foods[:peanut_oil]},
|
||||
{quantity: '1', units: 'pound', preparation: '', food: foods[:broccoli]},
|
||||
].each_with_index do |ri, i|
|
||||
RecipeIngredient.create!({recipe: bb, sort_order: i}.merge(ri))
|
||||
end
|
||||
|
@ -20,7 +20,9 @@ module Unitwise
|
||||
def self.with_custom_units(unit_list, &block)
|
||||
|
||||
atoms = []
|
||||
ret_val = nil
|
||||
|
||||
begin
|
||||
unit_list.each do |u|
|
||||
atom = Unitwise::Atom.new(u)
|
||||
atom.validate!
|
||||
@ -30,13 +32,14 @@ module Unitwise
|
||||
rem = Unitwise::Expression::Decomposer.send(:reset)
|
||||
|
||||
ret_val = block.call
|
||||
|
||||
ensure
|
||||
atoms.each do |a|
|
||||
idx = Unitwise::Atom.all.index { |b| b.equal?(a) }
|
||||
Unitwise::Atom.all.delete_at(idx)
|
||||
# Unitwise::Atom.all.pop
|
||||
end
|
||||
Unitwise::Expression::Decomposer.send(:reset, rem)
|
||||
end
|
||||
|
||||
ret_val
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user