Home > Enterprise >  How can I calculate Array variable of a Model in another Model?
How can I calculate Array variable of a Model in another Model?

Time:12-12

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
  • Related