开发者

Rails: using find method to access joined tables for polymorphic relationships

开发者 https://www.devze.com 2023-01-01 06:58 出处:网络
Ok, I have a generic TimeSlot model that deals with a start_at and an end_at for time spans. A couple models derive from this but I\'m referring to one in this question: AppointmentBlock which is a co

Ok, I have a generic TimeSlot model that deals with a start_at and an end_at for time spans. A couple models derive from this but I'm referring to one in this question: AppointmentBlock which is a collection of Appointments. I want to validate an AppointmentBlock such that no other AppointmentBlocks have been scheduled for a particular Employee in the same time frame. Since AppointmentBlock has a polymorphic association with TimeSlot, you have to access the AppointmentBlock's start_at and end_at through the Tim开发者_运维百科eSlot like so: appt_block.time_slot.start_at This means that I need to have some kind of join in my :conditions for my find() method call. Here is my code so far:

#inside my time_slot.rb model
belongs_to :time_slot_role, :polymorphic => true

 

#inside my appointment_block.rb model
has_one :time_slot, :as => :time_slot_role, :dependent => :destroy
validate :employee_not_double_booked

def employee_not_double_booked
  unless self.employee_id
    # this find's condition is incorrect because I need to join time_slots to get access
    # to start_at and end_at. How can I do this?
    blocks = AppointmentBlock.find(:first,
      :conditions => ['employee_id = ? and (start_at between ? and ? or end_at between ? and ?)',
      self.employee_id, self.time_slot.start_at, self.time_slot.end_at,
      self.time_slot.start_at, self.time_slot.end_at])
    # pseudo code:
    # collect a list of appointment blocks that end after this
    # apointment block starts or start before this appointment
    # block ends that are also associated with this appointment
    # blocks assigned employee
    # if the count is great then 0 the employee has been double
    # booked.

    # if a block was found that means this employee is getting
    # double booked so raise an error
    errors.add "AppointmentBlock",
      "has already been scheduled during this time" if blocks
  end
end

Since AppointmentBlock doesn't have a start_at or an end_at how can I join with the time_slots table to get those conditions to work?


You can use the :joins parameter on find, similar to this:

 blocks = AppointmentBlock.find(:first,
          :conditions => ['employee_id = ? and (time_slots.start_at between ? and ? or time_slots.end_at between ? and ?)',
            self.employee_id, self.time_slot.start_at, self.time_slot.end_at,
            self.time_slot.start_at, self.time_slot.end_at],
          :joins => 'join time_slots on time_slots.time_slot_role_id = appointment_blocks.id')
0

精彩评论

暂无评论...
验证码 换一张
取 消