Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor User model #86

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
9 changes: 9 additions & 0 deletions app/models/ingredient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,13 @@ class Ingredient < ApplicationRecord

has_many :meal_ingredients, dependent: :destroy
has_many :meals, through: :meal_ingredients

def self.to_data
all.map do |ingredient|
{
name: ingredient.name,
avg_gut_feeling: ingredient.avg_gut_feeling.abs.round(2)
}
end
end
end
60 changes: 22 additions & 38 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,32 @@ def ratings_needed
12 - meals.where.not(gut_feeling: nil).count
end

def worst_ingredients_data
worst_ingredients.map do |ingredient|
{
name: ingredient.name,
avg_gut_feeling: ingredient.avg_gut_feeling.abs.round(2)
}
end[0..24]
end

def ingredient_table_data
ingredients.joins(:meals).
includes(:foods).
select('ingredients.*, avg(meals.gut_feeling) as avg_gut_feeling, sqrt(count(ingredients.id)) as frequency').
group('ingredients.id').
order('avg_gut_feeling')
end

def worst_ingredients
ingredients.joins(:meals).
select('ingredients.name, avg(meals.gut_feeling) as avg_gut_feeling, sqrt(count(ingredients.id)) as frequency').
group('ingredients.id').
having('avg(meals.gut_feeling) < 0').
having('count(ingredients.id) > 2').
order('avg_gut_feeling')
ingredients
.joins(:meals)
.includes(:foods)
.select('ingredients.*, avg(meals.gut_feeling) as avg_gut_feeling, sqrt(count(ingredients.id)) as frequency')
.group('ingredients.id')
.order('avg_gut_feeling')
end

def best_ingredients_data
best_ingredients.map do |ingredient|
{
name: ingredient.name,
avg_gut_feeling: ingredient.avg_gut_feeling.round(2)
}
end[0..24]
end
def sorted_ingredients(flag, count)
if flag == 'best'
order = 'DESC'
range = [0, 6]
else
order = 'ASC'
range = [-6, 0]
end

def best_ingredients
ingredients.joins(:meals).
select('ingredients.name, avg(meals.gut_feeling) as avg_gut_feeling, sqrt(count(ingredients.id)) as frequency').
group('ingredients.id').
having('avg(meals.gut_feeling) > 0').
having('count(ingredients.id) > 2').
order('avg_gut_feeling DESC')
ingredients
.joins(:meals)
.select('ingredients.*, avg(meals.gut_feeling) as avg_gut_feeling')
.group('ingredients.id')
.having('avg(meals.gut_feeling) > ? AND avg(meals.gut_feeling) < ?', range[0], range[1])
.having('count(ingredients.id) > 2')
.order("avg_gut_feeling #{order}, ingredients.name")
.limit(count)
end

def gut_feelings_over_time
Expand Down
4 changes: 2 additions & 2 deletions app/views/results/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
<%= content_tag :div, '',
id: 'worst-ingredients-graph',
class: 'm-auto',
data: {ingredients: current_user.worst_ingredients_data} %>
data: {ingredients: current_user.sorted_ingredients('worst', 25).to_data} %>
</article>

<article class="best-graph">
<h3>Best Ingredients</h3>
<%= content_tag :div, '',
id: 'best-ingredients-graph',
class: 'm-auto',
data: {ingredients: current_user.best_ingredients_data} %>
data: {ingredients: current_user.sorted_ingredients('best', 25).to_data} %>
</article>
</section>

Expand Down
3 changes: 3 additions & 0 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,7 @@

# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false

# Configure Amazon Cloud Services
config.action_controller.asset_host = "d2abalslql541q.cloudfront.net"
end
56 changes: 56 additions & 0 deletions spec/models/ingredient_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,60 @@
it { should have_many :meal_ingredients }
it { should have_many(:meals).through(:meal_ingredients) }
end

describe 'class methods' do
it 'to_data' do
user = create(:user)

meal_1 = create(:meal, user: user, gut_feeling: -5)
meal_2 = create(:meal, user: user, gut_feeling: -4)
meal_3 = create(:meal, user: user, gut_feeling: -3)
meal_4 = create(:meal, user: user, gut_feeling: -2)
meal_5 = create(:meal, user: user, gut_feeling: -1)
meal_6 = create(:meal, user: user, gut_feeling: 0)
meal_7 = create(:meal, user: user, gut_feeling: 1)
meal_8 = create(:meal, user: user, gut_feeling: 2)
meal_9 = create(:meal, user: user, gut_feeling: 3)
meal_10 = create(:meal, user: user, gut_feeling: 4)
meal_11 = create(:meal, user: user, gut_feeling: 5)
meal_12 = create(:meal, user: user, gut_feeling: 2)

ingredient_1 = create(:ingredient) # avg: -4.0
ingredient_2 = create(:ingredient) # avg: -1.0
ingredient_3 = create(:ingredient) # avg: -3.67
ingredient_4 = create(:ingredient) # avg: -0.67
ingredient_5 = create(:ingredient) # avg: -0.25
ingredient_6 = create(:ingredient) # avg: -1.33
ingredient_7 = create(:ingredient) # avg: +2.5
ingredient_8 = create(:ingredient) # avg: +0.25
ingredient_9 = create(:ingredient) # avg: +2.0
ingredient_10 = create(:ingredient) # avg: +3.67
ingredient_11 = create(:ingredient) # avg: +1.33
ingredient_12 = create(:ingredient) # avg: +3.5

meal_1.ingredients.push(ingredient_1, ingredient_3, ingredient_11)
meal_2.ingredients.push(ingredient_1, ingredient_3, ingredient_8)
meal_3.ingredients.push(ingredient_1, ingredient_2, ingredient_6)
meal_4.ingredients.push(ingredient_4, ingredient_5, ingredient_3)
meal_5.ingredients.push(ingredient_4, ingredient_5, ingredient_6)
meal_6.ingredients.push(ingredient_8, ingredient_5, ingredient_6)
meal_7.ingredients.push(ingredient_4, ingredient_9, ingredient_2)
meal_8.ingredients.push(ingredient_8, ingredient_9, ingredient_5)
meal_9.ingredients.push(ingredient_7, ingredient_8, ingredient_9)
meal_10.ingredients.push(ingredient_10, ingredient_11)
meal_11.ingredients.push(ingredient_10, ingredient_11, ingredient_12)
meal_12.ingredients.push(ingredient_10, ingredient_12, ingredient_7)

expected = [
{ avg_gut_feeling: 3.67, name: ingredient_10.name },
{ avg_gut_feeling: 3.50, name: ingredient_12.name },
{ avg_gut_feeling: 2.50, name: ingredient_7.name },
{ avg_gut_feeling: 2.00, name: ingredient_9.name },
{ avg_gut_feeling: 1.33, name: ingredient_11.name },
{ avg_gut_feeling: 0.25, name: ingredient_8.name }
]

expect(user.sorted_ingredients('best', 6).to_data).to eq(expected)
end
end
end
88 changes: 38 additions & 50 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,61 +61,49 @@
@meal_11 = create(:meal, user: @user, gut_feeling: 5, created_at: 'Tue, 24 Dec 2019 14:54:09 UTC +00:00')
@meal_12 = create(:meal, user: @user, gut_feeling: 2, created_at: 'Tue, 24 Dec 2019 14:54:09 UTC +00:00')

ingredient_1 = create(:ingredient)
ingredient_2 = create(:ingredient)
ingredient_3 = create(:ingredient)
ingredient_4 = create(:ingredient)
ingredient_5 = create(:ingredient)
ingredient_6 = create(:ingredient)
ingredient_7 = create(:ingredient)
ingredient_8 = create(:ingredient)
ingredient_9 = create(:ingredient)
ingredient_10 = create(:ingredient)
ingredient_11 = create(:ingredient)
ingredient_12 = create(:ingredient)

@meal_1.ingredients.push(ingredient_1, ingredient_3)
@meal_2.ingredients.push(ingredient_1, ingredient_3)
@meal_3.ingredients.push(ingredient_1, ingredient_2, ingredient_3)
@meal_4.ingredients.push(ingredient_4, ingredient_5, ingredient_6)
@meal_5.ingredients.push(ingredient_4, ingredient_5, ingredient_6)
@meal_6.ingredients.push(ingredient_4, ingredient_5, ingredient_6)
@meal_7.ingredients.push(ingredient_8, ingredient_9)
@meal_8.ingredients.push(ingredient_8, ingredient_9)
@meal_9.ingredients.push(ingredient_7, ingredient_8, ingredient_9)
@meal_10.ingredients.push(ingredient_10, ingredient_11, ingredient_12)
@meal_11.ingredients.push(ingredient_10, ingredient_11, ingredient_12)
@meal_12.ingredients.push(ingredient_10, ingredient_12)
@ingredient_1 = create(:ingredient) # avg: -4.0
@ingredient_2 = create(:ingredient) # avg: -1.0
@ingredient_3 = create(:ingredient) # avg: -3.67
@ingredient_4 = create(:ingredient) # avg: -0.67
@ingredient_5 = create(:ingredient) # avg: -0.25
@ingredient_6 = create(:ingredient) # avg: -1.33
@ingredient_7 = create(:ingredient) # avg: +2.5
@ingredient_8 = create(:ingredient) # avg: +0.25
@ingredient_9 = create(:ingredient) # avg: +2.0
@ingredient_10 = create(:ingredient) # avg: +3.67
@ingredient_11 = create(:ingredient) # avg: +1.33
@ingredient_12 = create(:ingredient) # avg: +3.5

@meal_1.ingredients.push(@ingredient_1, @ingredient_3, @ingredient_11)
@meal_2.ingredients.push(@ingredient_1, @ingredient_3, @ingredient_8)
@meal_3.ingredients.push(@ingredient_1, @ingredient_2, @ingredient_6)
@meal_4.ingredients.push(@ingredient_4, @ingredient_5, @ingredient_3)
@meal_5.ingredients.push(@ingredient_4, @ingredient_5, @ingredient_6)
@meal_6.ingredients.push(@ingredient_8, @ingredient_5, @ingredient_6)
@meal_7.ingredients.push(@ingredient_4, @ingredient_9, @ingredient_2)
@meal_8.ingredients.push(@ingredient_8, @ingredient_9, @ingredient_5)
@meal_9.ingredients.push(@ingredient_7, @ingredient_8, @ingredient_9)
@meal_10.ingredients.push(@ingredient_10, @ingredient_11)
@meal_11.ingredients.push(@ingredient_10, @ingredient_11, @ingredient_12)
@meal_12.ingredients.push(@ingredient_10, @ingredient_12, @ingredient_7)
end

it 'best_ingredients' do
result = @user.best_ingredients
it 'sorted_ingredients' do
worst_result = @user.sorted_ingredients('worst', 6)

expect(result.length).to eq(5)
expect(result.first.avg_gut_feeling).to eq(4.5)
expect(result.last.avg_gut_feeling).to eq(2)
end

it 'best_ingredients_data' do
result = @user.best_ingredients_data

expect(result.count).to eq(5)
expect(result.first.keys).to eq(%i[name avg_gut_feeling])
end

it 'worst_ingredients' do
result = @user.worst_ingredients

expect(result.length).to eq(5)
expect(result.first.avg_gut_feeling).to eq(-4)
expect(result.last.avg_gut_feeling).to eq(-1)
end
expect(worst_result.length).to eq(6)
expect(worst_result.first.avg_gut_feeling).to eq(-4)
expect(worst_result.last.avg_gut_feeling).to eq(-0.25)
expect(worst_result.first.name).to eq(@ingredient_1.name)
expect(worst_result.last.name).to eq(@ingredient_5.name)

it 'worst_ingredients_data' do
result = @user.worst_ingredients_data
best_result = @user.sorted_ingredients('best', 5)

expect(result.count).to eq(5)
expect(result.first.keys).to eq(%i[name avg_gut_feeling])
expect(best_result.length).to eq(5)
expect(best_result.first.avg_gut_feeling.round(2)).to eq(3.67)
expect(best_result.last.avg_gut_feeling.round(2)).to eq(1.33)
expect(best_result.first.name).to eq(@ingredient_10.name)
expect(best_result.last.name).to eq(@ingredient_11.name)
end

it 'gut_feelings_over_time' do
Expand Down