# Performing calculations using scopes

hello , hopefully this isn’t too ambitious but i am hoping there is a way to do simple summation using defined scopes example is i have these scopes :

``````      scope :present, -> { where(present: true) }
scope :absent, -> { where(present: false) }
scope :emergency_leave, -> { where(present: false) && where(reason: "Emergency Leave") }
scope :sick_leave, -> { where(present: false) && where(reason: "Sick Leave") }
scope :planned_leave, -> { where(present: false) && where(reason: "Planned Leave") }
``````

is it possible to define a method within the same class that can take something like
def x
absent.count + emergency_leave.count ?
end

how would you re-use the scopes to do calculations ?

Hey John,

You can absolutely make a method that adds the counts like that. You wouldn't be able to turn that method into a scope, because it's not returning a relation, but rather a number.

Also I'd suggest combining your where clauses for cleanliness:

``````# Convert
where(present: false) && where(reason: "Emergency Leave")
# to
where(present: false, reason: "Emergency Leave")
``````

super awesome thanks

Hi Chris,

The above scopes are in my attendance.rb but i would wish the method to be in attendance_sheet.rb , rem

``````  class AttendanceSheet < ActiveRecord::Base
has_many :attendances, dependent: :destroy
accepts_nested_attributes_for :attendances, reject_if: :all_blank, allow_destroy: true
belongs_to :team
end
``````

is it even possible to call that method from outside attendance_sheet while the scopes live in attendance ?

cheers

You can access the scopes through the attendances association if that's what you're asking. It should look like this:

``````# First we need a sheet
@attendance_sheet = AttendanceSheet.first

# Give me all the present attendances for that sheet
@attendance_sheet.attendances.present
``````

That is fine, I am do so currently , my question was where will the custom method be ? same class as scope or elsewhere

``````  def ps
(attendances.planned_leave.count + b.attendances.maternity_leave.count)  / b.attendances.count.to_f * 100
end

#@attendance_sheet.attendaces.ps doesnt work
``````

I am assuming is in the attendance.rb .... then how do i call it form attendance_sheet view

Ah, so those methods should actually be class methods!

``````def self.ps
(attendances.planned_leave.count + b.attendances.maternity_leave.count)  / b.attendances.count.to_f * 100
end
``````

Note the `self.` there in the name. That makes it a class method which makes it work like a scope would.

This lets you do this:

``````@attendance_sheet.attendaces.ps
``````

The reason being is that when you access a has_many association, it returns a Relation object that functions more like the model class instead of an individual record.

got yah !

the if its a class method in attendance.rb the it should read like this ?

``````  def self.planned_shrinkage
(planned_leave.count + maternity_leave.count + paternal_leave.count)  / present.count.to_f * 100
end

no attendaces.planned_leave. count but planned leave .count
``````

Yeah, if it's in the Attendance model where the scopes are, you can just use those methods directly without having "attendances" first so just `planned_leave`.

If you do it in the AttendanceSheet model, you'll need to preface the scopes with the attendances association `attendances.planned_leave`.

Awesome works like magic .. and when referring to the model its-self i can just use the keyword self !!!

Chris You Rock \m/ :)

Join the discussion

## Want to stay up-to-date with Ruby on Rails?

Join 84,111+ developers who get early access to new tutorials, screencasts, articles, and more.