Reputation: 345
I have a model, teams that has an instance method point_differential (basically points for - points against). I am trying to use it in a chartkick graph, but with no luck.
This works
= bar_chart Team.group(:group).sum(points_for)
because points_for is just an attribute of the Team model.
This doesn't because point_differential is an instance method, not an attribute
= bar_chart Team.group(:name).sum(point_differential)
Neither does
= bar_chart Team.group(:name).sum(&:point_differential)
Neither does
bar_chart = Team.all.map {|team| {name:team.name, point_differential: team.point_differential}}
Any ideas?
Upvotes: 2
Views: 1269
Reputation: 345
I resolved this by writing a class method to build a hash using inject
def self.hashify_points_differential
Player.all.inject({}) do |result, player|
result[player.name] = player.point_differential
result
end
end
Then I can just use it like
= bar_chart Player.hashify_points_differential
Upvotes: 1
Reputation: 11647
Your last option there is almost correct, but you have the wrong format.
Consider your first example:
Team.group(:group).sum(:points_for)
This would create a hash like the following:
{"Team A" => 14, "Team B" => 9}
In your last example you did this:
Team.all.map {|team| {name:team.name, point_differential: team.point_differential}}
Which would create an array of hashes like the following:
[{:name => "Team A", :point_differential => 14}, {:name => "Team B", :point_differential => 9}]
Instead, try this:
Hash[ *Team.all.map { |team| [team.name, team.point_differential] }.flatten ]
This is an esoteric one liner that takes an array of arrays (each 2 elements), and creates a hash out of them, giving you something like this:
{"Team A" => 14, "Team B" => 9 }
Like you want.
Another way, showing more steps to do this, is like this:
hash = {}
Team.all.each do |team|
hash[team.name] = team.point_differential
end
Then that hash
will have the right values.
Upvotes: 4