Skip to main content

custom method in class to perfom simple calculation

General • Asked by John Munyi

Hi Chris,

Checkout mt simple scenario below: I am trying to get the total count of all absent and present person from an attendance sheet here are my models.

 class AttendanceSheet < ActiveRecord::Base
    attr_accessor :totalp, :totala
  has_many :attendances
  accepts_nested_attributes_for :attendances, reject_if: :all_blank, allow_destroy: true
  belongs_to :team


  def total_present_agents
    totalp=AttendanceSheet.find(need to pass id here).attendances.where(present: true).count
  end

  def total_absent_agent
    totala=AttendanceSheet.find(need to pass id here).attendances.where(present: false).count
  end

end

The summary is to be displayed on the show page of the attendance sheet , in the show view i have this to display buy it runs without errors but displays nothing

<h2>Attendance statistics</h2>

<h5>Total present Agents <%= @attendance_sheet.totalp %></h5>
<h5>Total absent Agents <%= @attendance_sheet.totala %></h5>

if pass the id hardocoded like this:
totala=AttendanceSheet.find(8).attendances.where(present: false).count
i get what i want but of course thats not ideal at all as i want to dynamically pass the ids

so my questions is do i have to store that value in the database as i am not currently ?, also is the method in my class well defined ... what i am i missing ? Do i need this

attr_accessor :totalp, :totala

my attendance model also looks like this if that will clear thing up a bit

class Attendance < ActiveRecord::Base
  belongs_to :attendance_sheet
  belongs_to :user 
end

I have a feeling its a simple fundamental convention i am breaking , would be glad if you point me towards that direction


You can simplify this by adding scopes to your attendances model.

scope :present, -> {where(present: true)}

Then in your view or controller you can call AttendanceSheet.find(0).attendances.present.count

The problem you are running into is that you're trying to find attendances for each attendance sheet without passing it an argument for find. You can iterate through this in a block in your view then do objectvar.attendances.present.count where objectvar is the block variable you pass in the view.

Also your method(s) total_absent_agent are defined in the model but you are not calling them in the controller or the view, so it's basically not doing anything.

It might be a good idea to scope what you are actually trying to constrain, in this case attendances. Then use activerecord's relationship of has many attendances to extend that object from your primary object, attendance_sheet.


thanks James, allow me to engage you further for clarity

scoping sounds like a good idea.. but my problem occurs when i try to call AttendanceSheet.find(0)..... how exactly is the syntax ?

i tried that previously and i kept running into ...no Attendace_sheet with 'id' = :id ..... where is it best to call that line ?, show controller or the show view ...

much appreciated


Hi James,

I have just tweaked it a little bit and it has worked thanks so much for the scoping idea.

Much appreciated !!! yessssss


Glad it worked out for you! (thumbsup)


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 27,623+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.