yas4891
yas4891

Reputation: 4862

Get the number of objects meeting a criteria in a two-level deep relation

The following code is working and Customer#number_appointments_in_month correctly returns the number of appointments within a certain months.

However, I feel like I am not using Rails capabilities. Should I rather use an SQL statement? Is there a more elegant way to write Customer#number_appointments_in_month?

The method

class Calendar < ActiveRecord::Base
  has_many :appointments
end

class Appointment < ActiveRecord::Base
  # property 'start_date' returns a DateTime
end

class Customer < ActiveRecord::Base
  has_many :calendar

  def number_appointments_in_month(month = Date.today.month, year = Date.today.year)
    calendar.sum do |cal| 
      apps = cal.appointments.select do |app| 
        year == app.start_date.year && month == app.start_date.month
      end
      apps.size
    end # calendars.sum
  end
end 

Upvotes: 0

Views: 58

Answers (1)

SudoGuru
SudoGuru

Reputation: 385

I suggest to you some separation of concerns between your different models. How about this ?

class Calendar < ActiveRecord::Base
  has_many :appointments
  def appointments_in_month month, year
    self.appointments.select do |app|
      app.in? month, year
    end
    app.length
  end
end

class Appointment < ActiveRecord::Base
  def in? month, year
    year == self.start_date.year && month == self.start_date.month
  end
end

class Customer < ActiveRecord::Base
  has_many :calendar
  def number_appointments_in_month month, year
    self.calendars.reduce(0) do |total,c|
      total + c.appointments_in_month(month, year)
    end
  end
end

Upvotes: 1

Related Questions