3

I have a table with columns 'id', 'resource_id', 'read_time', 'value' where 'value' is a float

What I am trying to accomplish is to return a list of records such that the 'value' of each record is the sum of all the records at a specific 'read_time' but having differing 'resource_id' values.

I am wondering if there is a clever way (ie not looping through all the entries) to accomplish this. Currently I am implementing something along these lines:

@aggregate_meters = []
@res_one_meters = Meter.find(:all, :conditions => ["resource_id = ?", 1])

@res_one_meters.each do |meter|
  read_time = meter.read_time
  value = meter.value
  if res_two_meter = Meter.find(:first, :conditions => ["resource_id = ? AND read_time = ?", 2, read_time ])
    value = value + res_two_meter.value
  end
  aggregate_meter = Meter.new(:read_time => read_time, :value => value, :resource_id => 3)
  @aggregate_meters.push(aggregate_meter)
end

Thank you.

1 Answer 1

5

ActiveRecord::Calculate is your friend here. Letting you do exactly what you want with one database call. It returns a hash using the unique values in the column used in the group as keys.

Here's the code you wrote, rewritten to use sum.

values = Meter.sum(:value, :group => :read_time)

values.each do |read_time, value|
  aggregate_meter = Meter.new(:read_time => read_time, :value => value, :resource_id => 3)
  @aggregates_meter.push(aggregate_meter)
end
Sign up to request clarification or add additional context in comments.

1 Comment

Amazing! Thank you very much. I did not know the :group option existed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.