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

where does the :resources association in the Reservation model come from? Do you need a Resource model for this to work? or is this another rails magic method.

@greenplastik
Copy link

also, could you give me an example of what the links (index, new, edit, destroy) would look like?

@superlou
Copy link
Author

I updated the gist. I was learning as I went, so there's a couple corrections. Resource was an older model that was replaced by models implementing Reservable. Links look like normal rails links since the controller looks like normal CRUD:

<%= link_to "New Reservation", new_reservation_path %>

@greenplastik
Copy link

I think I'm starting to understand this. Any chance you could gist the relevant part of the schema that goes along with this?

I ask because I'm still not certain as to how the tables interrelate. Seeing the foreign keys would help. Sorry to keep bugging.

@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