Reputation: 81
Im trying to refactor my code in the Team model. Teams has:many Projections, and Projections has stats for a player (goals, assists, hits etc). I want to implement one method that can tally a specific total if you pass it the parameter you are looking for.
Something like this, where I could call: example_team.total(goals) or example_team.total(assists)
class Team < ApplicationRecord
# def total(value)
# total = 0
# self.projections.each do |projection|
# total += projection.value
# end
# return total
# end
The issue im having is that im essentially trying to pass a method name within a different method as a parameter. Im getting errors when im trying to do this. How can I get this refactoring to work???
This is my current unfactored code:
class Team < ApplicationRecord
def goals
total = 0
self.projections.each do |projection|
total += projection.goals
end
return total
end
def assists
total = 0
self.projections.each do |projection|
total += projection.assists
end
return total
end
def pp_points
total = 0
self.projections.each do |projection|
total += projection.pp_points
end
return total
end
def hits
total = 0
self.projections.each do |projection|
total += projection.hits
end
return total
end
def blocks
total = 0
self.projections.each do |projection|
total += projection.blocks
end
return total
end
Upvotes: 0
Views: 41
Reputation: 1836
To send a method dynamically you can use public_send.
class Team < ApplicationRecord
def total(field)
total = 0
self.projections.each do |projection|
total += projection.public_send(field)
end
return total
end
end
To simplify the example we can use sum that takes a symbol as an argument.
class Team < ApplicationRecord
def total(field)
projections.sum(field)
end
end
To make it work you should use something like this example_team.total(:goals)
.
Upvotes: 3