lemonginger
lemonginger

Reputation: 345

Using instance methods with chartkick in a rails app

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

Answers (2)

lemonginger
lemonginger

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

MrDanA
MrDanA

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

Related Questions