I have a simple Rails application. I am trying to calculate each usage time of Instruments inside Service Model.How can I calculate it inside the Service Model?
class Service < ApplicationRecord
has_many :instruments
def total_usage
# I want to sum the usage arrays which is from the Instrument model.
# Here
end
end
class Instrument < ApplicationRecord
belongs_to :service, dependent: :destroy
def usage
outtime = self.out_time
intime = self.in_time
usage = ((outtime - intime)/60.0).round.abs
end
end
CodePudding user response:
Its almost always preferable to do simple aggregations and calculations in the DB so that you can use them in ordering the records:
# Postgres
Service.select(
'services.*',
'SUM(instruments.time_diff) AS usage'
).joins(
'LATERAL (
SELECT instruments.out_time - instruments.in_time AS time_diff
FROM instruments
WHERE instruments.service_id = services.id
) instruments'
)
# MySql
Service.group(:id)
.select(
'services.*',
'SUM(
SELECT DATEDIFF(instruments.out_time, instruments.in_time)
FROM instruments
WHERE instruments.service_id = services.id
) AS usage'
)
This also avoids loading and instanciating all the related records if you just need aggregates and not the entire record.
CodePudding user response:
def total_usage
# or instruments.sum(&:usage) for short
instruments.sum { |instrument| instrument.usage }
end
btw, dependent: :destroy
should be placed after has_many
has_many :instruments, dependent: :destroy