Reputation: 2244
I've got three methods like this:
def total_fat
total = 0
meal_foods = current_user.meal_foods
meal_foods.each do |food|
total += food.fat
end
return total
end
One for fat, carbs, and protein.
I'd like to DRY this up.
I've tried this method and it didn't seem to work by passing in the 'macro' as string.
def total_of(macro)
total = 0
meal_foods = current_user.meal_foods
meal_foods.each do |food|
total += food.macro
end
return total
end
How could I do this?
Upvotes: 0
Views: 60
Reputation: 91
def total_of(type)
current_user.meal_foods.map(&:type).sum
end
total_of(:fat)
Upvotes: 1
Reputation: 12251
def total_of(macro)
current_user.meal_foods.inject(0) do |total,food|
total + food.send(macro)
end
end
I'm not certain this will work as you've provided no data to try it with, but have a look at the Enumerable docs to give you some ideas of what can be done. each_with_object
is underused and would fit here too.
There's no need for the explicit return. In fact, there's no need to even mention total
as it will be the last expression evaluated.
Upvotes: 0
Reputation: 18567
def total_of(marcro)
current_user.meal_foods.map(&marcro).inject(:+)
end
This takes the Array(-like) collection of meal_foods
and maps it to an Array of just the marcro
value of the meal_foods
, and then injects a "+" between each of the numbers. Make sure to pass the argument as a symbol, e.g. total_of(:fat)
.
Upvotes: 3
Reputation: 6856
You need to use send to invoke methods with variables, and convert macro to a symbol.
so:
food.send(macro.to_sym)
Upvotes: 0