upto 4.4: favorite_brewery, extracted favorite_attribute

This commit is contained in:
Aaro Koivukangas
2023-08-16 11:52:03 +03:00
parent d8455d2867
commit 7dfff96dcb
2 changed files with 58 additions and 19 deletions
+36 -16
View File
@@ -20,27 +20,47 @@ class User < ApplicationRecord
end end
def favorite_style def favorite_style
# create hash with key being style name and value first 0 and then the score styles = favorite_attribute "styles"
styles = {} item_with_most_points(styles)
ratings.each do |rating| end
if styles[rating.beer.style].nil?
styles[rating.beer.style] = rating.score def favorite_brewery
else breweries = favorite_attribute "breweries"
styles[rating.beer.style] += rating.score item_with_most_points(breweries)
end
end
# determine which style hast the most points
style_with_most_points(styles)
end end
private private
def style_with_most_points(styles) def favorite_attribute(target)
# not the fastest implementation but its DRY complient
items = {}
ratings.each do |rating|
attributes = {
# create hash with key being style name and value first 0 and then the score
"styles" => rating.beer.style,
# iterate through ratings and add scores depending on
# which brewery the beer that was rated was made in
"breweries" => rating.beer.brewery.name
}
raise "Incorrect target" if attributes[target].nil?
if items[attributes[target]].nil?
items[attributes[target]] = rating.score
else
items[attributes[target]] += rating.score
end
end
items
end
def item_with_most_points(items)
highest = { name: "", total: 0 } highest = { name: "", total: 0 }
styles.each do |style| items.each do |item|
if style[1] > highest[:total] if item[1] > highest[:total]
highest[:name] = style[0] highest[:name] = item[0]
highest[:total] = style[1] highest[:total] = item[1]
end end
end end
highest[:name] highest[:name]
+22 -3
View File
@@ -41,7 +41,7 @@ RSpec.describe User, type: :model do
end end
it "returns the most liked style" do it "returns the most liked style" do
create_beer_with_many_ratings({user: user}, 10, 10, 20) create_beer_with_many_ratings({user: user, brewery: brewery}, 10, 10, 20)
beer_with_favorite_style = FactoryBot.create(:beer, style: "No") beer_with_favorite_style = FactoryBot.create(:beer, style: "No")
FactoryBot.create(:rating, beer: beer_with_favorite_style, score: 50, user: user) FactoryBot.create(:rating, beer: beer_with_favorite_style, score: 50, user: user)
@@ -49,17 +49,36 @@ RSpec.describe User, type: :model do
end end
it "also returns the most liked style" do it "also returns the most liked style" do
create_beer_with_many_ratings({user: user}, 20, 30, 20) create_beer_with_many_ratings({user: user, brewery: brewery}, 20, 30, 20)
beer_with_favorite_style = FactoryBot.create(:beer, style: "No") beer_with_favorite_style = FactoryBot.create(:beer, style: "No")
FactoryBot.create(:rating, beer: beer_with_favorite_style, score: 50, user: user) FactoryBot.create(:rating, beer: beer_with_favorite_style, score: 50, user: user)
expect(user.favorite_style).to eq "Yes" expect(user.favorite_style).to eq "Yes"
end end
end end
describe "favorite_brewery" do
let(:user){ FactoryBot.create(:user) }
let(:brewery1){ FactoryBot.create(:brewery) }
let(:brewery2){ FactoryBot.create(:brewery, name: "Boring") }
before do create_beer_with_many_ratings({user: user, brewery: brewery1}, 20, 30, 20, 40) end
before do create_beer_with_many_ratings({user: user, brewery: brewery2}, 20, 30, 20, 50) end
it "is a defined method" do
expect(user).to respond_to(:favorite_brewery)
end
it "returns a string" do
expect(user.favorite_brewery).to be_a(String)
end
it "returns the correct brewery" do
expect(user.favorite_brewery).to eq "Boring"
end
end
end end
def create_beer_with_rating(object, score) def create_beer_with_rating(object, score)
beer = FactoryBot.create(:beer) beer = FactoryBot.create(:beer, brewery: object[:brewery])
rating = FactoryBot.create(:rating, beer: beer, score: score, user: object[:user]) rating = FactoryBot.create(:rating, beer: beer, score: score, user: object[:user])
end end