From: dohzya Date: 2007-07-25T03:38:17+09:00 Subject: Bidirectionnal relation Hi everyone, I have a problem with bidirectional relations : how to implements it ? I can't implements it with 2 relations without synchronize them : --- # no synchronization class Entity attr_accessor :mother attr_reader :daughters def initialize @daughters = [] end end a = Entity.new b = Entity.new a.mother = b puts (b.daughters.include? a) # false a.daughters << b puts (b.mother == a) # false --- too bad... Try with a simple synchronization : --- # simple synchronization class Entity attr_reader :mother, :daughters def initialize @daughters = [] end def mother= m @mother.daughters.delete self unless @mother.nil? @mother = m @mother.daughters << self unless @mother.nil? end def add_daughter d unless d.nil? @daughters << d d.mother = self end end end a = Entity.new b = Entity.new a.mother = b puts (b.daughters.include? a) # true a.daughters << b # it's possible so why not use it ? puts (b.mother == a) # false --- ok for some operations, but not exhaustive. The problem seems to come from @daughters which is a simple Array. Let's fix it : --- # better synchronization class Entity attr_reader :mother, :daughters def initialize @daughters = [] class << @daughters attr_accessor :mother alias __old_add__ << def << d, recc=false __old_add__ d d.mother = @mother unless recc end alias __old_delete__ delete def delete d if include? d d.mother = nil __old_delete__ d end end end @daughters.mother = self end def mother= m @mother.daughters.delete self unless @mother.nil? @mother = m @mother.daughters.<<(self, true) unless @mother.nil? end def add_daughter d unless d.nil? @daughters << d d.mother = self end end end a = Entity.new b = Entity.new a.mother = b puts (b.daughters.include? a) # true a.daughters << b puts (b.mother == a) # true --- ok it works (I think), but I need to redefine all methods from @daughters... 26 lines more than the first (and natural) solution, for a really simple problem... I don't think I'll often use it. I tried to implement a solution with a real relation, but I had too many problems. If anyone has a suggestion (solution or link or anything) to implement transparent bidirectional relation... :) Thanks ! -- Etienne Vallette d'Osia