Skip to content

Instantly share code, notes, and snippets.

@superlou
Created April 22, 2011 00:44
Show Gist options
  • Save superlou/935790 to your computer and use it in GitHub Desktop.
Save superlou/935790 to your computer and use it in GitHub Desktop.
Modeling polymorphic has_many :through
A user creates Spaces (rooms), Items (things), and Profiles (people).
Reservations are used to schedule times when these three models are in use and cannot be used elsewhere.
Since the modeling of a thing that can only be in use in one place/activity is common to Spaces, Items, and Profiles, this common functionality makes up the polymorphic model Resource.
Reservation
belongs_to :manager, :class_name => "Profile"
has_many :reservation_lines, :before_add => :set_nest, :dependent => :destroy
has_many :profiles, :through => :reservation_lines, :source => :reservable, :source_type => 'Profile'
has_many :spaces, :through => :reservation_lines, :source => :reservable, :source_type => 'Space'
has_many :items, :through => :reservation_lines, :source => :reservable, :source_type => 'Item'
accepts_nested_attributes_for :reservation_lines, :allow_destroy => true,
:reject_if => proc {|attributes| attributes['reservable_id'].blank?}
ReservationLine
belongs_to :reservation
belongs_to :reservable, :polymorphic => true
Profile
include ReservableMixin
Space
include ReservableMixin
Item
include ReservableMixin
module ReservableMixin
def self.included(base)
base.has_many :reservation_lines, :as => :reservable
base.has_many :reservations, :through => :reservation_lines
end
def reservations_overlapping(range)
overlapping = reservations.select {|r| r.range.overlap?(range)}
end
end
@greenplastik
Copy link

I assume you have five tables:

reservations, reservation_lines, profiles, spaces, and item. And only the reservation_lines table has (two) foreign keys: reservation_id and reservable_id (with reservable_type). is that right?

@superlou
Copy link
Author

Yep. The only foreign keys (ignoring the one for manager of a reservation) are reservation_id (:integer) and reservable_id (:integer) and reservable_type (:string).

@greenplastik
Copy link

greenplastik commented Apr 27, 2011 via email

@superlou
Copy link
Author

I'm new to this, so take this with a grain of salt. Good luck railsing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment