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")
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/ :)