Skip to content

Instantly share code, notes, and snippets.

@ndelage
Created April 14, 2014 19:02
Show Gist options
  • Save ndelage/10674675 to your computer and use it in GitHub Desktop.
Save ndelage/10674675 to your computer and use it in GitHub Desktop.
Advanced ActiveRecord Assocations
require 'active_record'
def setup
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
end
def generate_migrations
ActiveRecord::Migration.create_table :hotels do |t|
t.string :name
t.integer :room_count
t.timestamps
end
ActiveRecord::Migration.create_table :rooms do |t|
t.belongs_to :hotel
t.integer :rate
t.timestamps
end
ActiveRecord::Migration.create_table :bookings do |t|
t.belongs_to :room
t.belongs_to :user
t.datetime :checkin
t.datetime :checkout
t.integer :rate
t.timestamps
end
ActiveRecord::Migration.create_table :users do |t|
t.string :name
t.timestamps
end
ActiveRecord::Migration.create_table :ratings do |t|
# Since we want multiple things to be rateable
# (hotels and rooms) we define the columns necessary
# for a polymorphic association (_id and _type)
t.integer :rateable_id
t.string :rateable_type
t.text :text
t.timestamps
end
# Here's an example of what the ratings table looks like after we create a
# few records.
# id rateable_id rateable_type text
# 1 1 "Hotel" "Great food."
# 2 1 "Room" "Wish there was a bed!"
end
def migrate
ActiveRecord::Migrator.up "db/migrate"
end
setup()
generate_migrations()
migrate()
class Hotel < ActiveRecord::Base
has_many :rooms
has_many :bookings, through: :rooms
has_many :booked_guests, through: :bookings, source: :guest
has_many :ratings, as: :rateable
def to_s
"#{name} with #{rooms.count} rooms"
end
end
class Booking < ActiveRecord::Base
belongs_to :room
belongs_to :guest, class_name: "User", foreign_key: "user_id"
end
class Room < ActiveRecord::Base
belongs_to :hotel
has_many :bookings
has_many :ratings, as: :rateable
end
class User < ActiveRecord::Base
has_many :bookings
has_many :booked_rooms, through: :bookings, source: :room
end
class Rating < ActiveRecord::Base
belongs_to :rateable, polymorphic: true
end
hotel = Hotel.create!(name: "Westin", room_count: 200)
hotel.rooms << Room.create!(rate: 200)
hotel.rooms << Room.create!(rate: 50)
puts Room.first.hotel
user = User.create!(name: "John Smith")
room = hotel.rooms.first
b = Booking.create!(guest: user, room: room)
room_rating = Rating.create!(rateable: room, text: "Wish there was a bed!")
hotel_rating = Rating.create!(rateable: hotel, text: "Food is great!")
p room_rating.rateable
p hotel_rating.rateable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment