D
dohzya
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 !
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 !