Ruby ActiveRecord: How to connect two rooms with an exit -


i making small text-adventure, , want use activerecord object relational mapping.

what i'm having trouble with, understanding how connect 2 rooms using exit. following facts given:

  • a room can have multiple exits
  • an exit can in different directions (it has 'direction' field). also, might have other parameters such 'locked', etc. want add later.
  • an exit connects 2 rooms.

however, stuck:

what have far

class room < activerecord::base     has_many :exits     has_many :neighbours, through: :exits end  class exit < activerecord::base      belongs_to :room, dependent: :destroy     belongs_to :room_dest, foreign_key: "room_dest_id", class_name: "room", dependent: :destroy  end 

but incomplete. room.neighbours, example, not working @ all.

what baffles me how make exits work two-ways: if add exit on 1 room, won't in room.exits list in other room.

what works is: (given exit connecting room1 , room2) room1.first.exits.first.room_dest (this room2) room2.exits empty, , room1.neighbours shows list containing itself.

how done properly?

to room.neighbours working, believe first need change

belongs_to :room_dest, foreign_key: "room_dest_id", class_name: "room", dependent: :destroy 

to

 belongs_to :neighbour, foreign_key: "room_dest_id", class_name: "room" 

note removed dependent: option because don't want destroy rooms when exits deleted. want dependent: :destroy on has_many relationship exits.

now we've solidified one-way binding of exit. if think it, isn't "exit" one-way definition? while seems limiting @ first, can utilize define "entrances" of room. connection neighbour original room. like:

has_many :entrances, class_name: "exit", foreign_key: "room_dest_id" 

or define method queries exits , checks if either room_id or room_dest_id room id. in case rename "exit" class more generic. unfortunately can't think of built-in ar association multi-key association you. wouldn't work right because things association.build/create not know of keys set. it's relatively simple method or set of methods still return scope operator on:

has_many :connections, dependent: :destroy # ease of creating connection, not useful querying them  def exits   connection.where(["room_id = :id or dest_room_id = :id", id: self.id]) end  def neighbours   exits.map |conn|     conn.room_id == self.id ? conn.dest : conn.source   end end 

you make query more complex if want of connections one-way. or write other methods build on since not executed immediately. still chain .first(), .where(), etc on it.


Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -