TIM
TIM

Reputation: 315

How to model many similar resources with minor differences elegantly in rails

still very new to the whole web programming with databases thing and happy about any hints you can give me.

I have been trying to wrap my head around this forever, now, but I can't seem to be able to find an elegant solution.

Let's say I have a hotel with several floors, e.g. 1st floor, 2nd floor, 3rd floor.

Let's also say there are several types of suites on each floor, e.g. president, honeymoon, emperor. Every suite has a number of rooms that belong to it. The rooms themselves vary in terms furniture.

Now, every type of suite can be found on one floor or several suites on many floors.

+1stFloor
   +president suite
      +room1
      +room2
   +honeymoon suite
      +room1
+2ndFloor
   +president suite
      +room1
      +room2
   +emperor suite
      +room1
      +room2
      +room3
+3rdFloor
   +emperor suite
      +room1
      +room2
      +room3
   +honeymoon suite
      +room1

So I could start with the floor model, continue with the suite model that belongs to the floor and a room model that belongs to the suite. Maybe the rooms even had different types of furniture in them, so room1, 2 and 3 are not similar, although room1 and a different room1 are. This get very complicated and I am not sure I am doing this right.

Another approach would be to model each suite as an entire separate resource

Any tips on how do do this right?

How do e.g. sellers of computer hardware model their catalog. Items of the same category share a lot of similar attributes, but they have so many categories...

Any hints, pointers or links to tutorials are greatly appreciated.

Thanks Tim

Upvotes: 0

Views: 64

Answers (2)

Dmitry Matveev
Dmitry Matveev

Reputation: 5376

You need something in the lines of:...

class Room < ActiveRecord
  belongs_to :suite
  validates :suite, presence: true #make sure room is not a rouge entry
  validates :floor_num, presence: true
end

class Suite < ActiveRecord
  has_many :rooms, dependent: :destroy
  validates :type, presence: true
end

with this arrangement you can make such calls like:

rooms = Room.find_by_floor_num('floor number') #returns all room at a given floor
suite = Suite.find 1 #returns a particular suite
suite_rooms = suite.rooms.all #returns all rooms for the given suite
suite_room = suite_rooms.first
suite_room_type = suite_room.suite.type

EDIT:

For the room furniture that will vary from room to room the best way is to create another model, say

class Room < ActiveRecord
   ...
   has_many :furniture
   ...
end

class Furniture < ActiveRecord
   belongs_to :room
   validates :room, presence: true
   validates :name, presence: true
end

Then as with the code above you can call methods like:

room.furniture.all #to get all pieces of furniture
table.room #to find the location of the lamp
# etc

Yet another EDIT

And of course if the room has furnishings that would mean that a suite has it too, so the only thing you need is to add one more association to Suite class like this

class Suite < ActiveRecord
   ...
   has_many :furniture, through: :rooms
   ...
end

Mind the plural form of 'rooms' here.
With this little code you can now call the following...

suite.furniture # get all pieces of furnishing from all the room in this suite

EDIT:
If for example you need your floors to contain more then just rooms, you will need to make use of polymorphic associations. Official ruby on rails guide on ActiveRecords Associations does a good job explaining how to use those :)

Hope this answers your question :) Good luck with you rails learning :) have a look at M.Hartl's tutorial, its a very well structured and informative place to begin with.

Upvotes: 0

Marcelo De Polli
Marcelo De Polli

Reputation: 29291

I thought it could be something like this.

class Floor < ActiveRecord::Base
  has_many :suites
end

class Suite < ActiveRecord::Base
  belongs_to :floor
  belongs_to :suite_category
  has_many :rooms, :dependent => :destroy
end

class SuiteCategory < ActiveRecord::Base
  has_many :suites
end

class Room < ActiveRecord::Base
  belongs_to :suite
  has_and_belongs_to_many :room_types
end

class RoomType < ActiveRecord::Base
  has_and_belongs_to_many :rooms
end

That way you can have many room_types with different furniture configurations and just associate your rooms to them. Kinda like tags.

Upvotes: 1

Related Questions