Relation many-to-many "compliquée"

Bonjour à tous,
j’ai un problème :
j’ai des connexions qui passent à travers des liens,équipements,ports
(un lien est entre deux ports de deux équipement, un port appartient Ã
un équipement)

j’ai donc comme relation entre ceux de droite :

class Link < ActiveRecord::Base
belongs_to :src_device, :class_name => “device”, :foreign_key =>
“src_device_id”
belongs_to :dst_device, :class_name => “device”, :foreign_key =>
“dst_device_id”
belongs_to :src_port, :class_name => “port”, :foreign_key =>
“src_port_id”
belongs_to :dst_port, :class_name => “port”, :foreign_key =>
“dst_port_id”

class Port < ActiveRecord::Base
belongs_to :device

has_many :links

class Device < ActiveRecord::Base
has_many :links
has_many :ports

Maintenant, je peux avoir plusieurs connexions sur un même
équipement/port/lien et je peux avoir plusieurs équipement/port/lien par
connexion.

Donc là je pensais rajouter cela à la connexion (en suivant ce qui est
dit dans ce lien :
http://paulbarry.com/articles/2007/10/24/has_many-through-checkboxes")
:

has_many :links, :through => :link_connections has_many :ports, :through => :port_connections has_many :devices, :through => :device_connections

et faire la symétrie pour les équipement/port/lien

Là ou ça se corse c’est qu’une connexion peut passer plusieurs fois par
le même équipement/port/lien…
Et là je vois pas trop comment faire, sauf créer un modèle
“ConnexionFragment” qui sera un fragment de connexion et qui lui aura
une relation one-to-many avec les connexions et une relation one-to-many
avec les équipement/port/lien (double one-to-many pour les
équipements/ports) mais je trouve que je perds pas mal de simplicité…

Vous auriez pas une idée plus simple/elegante ?

Je ne sais pas si je suis le seul, mais en toute franchise je ne suis
pas
sûr d’avoir bien compris ce que tu cherches à faire.

Bon, au cas où j’aurais compris, tu as des

  • devices, qui ont des ports
  • ports qui sont sur des devices, qui ont des connexion
  • connexions qui sont sur deux ports différents chaque

Et si je comprends bien tu as modélisé ça comme ça :

  • [device, port] <=> connexion <=> [port, device]

Hmm. Ca m’a l’air compliqué. C’est moi où je sens l’odeur
caractéristique du
pattern-spaghetti brûlé ?

Attends, pourtant il semblerait qu’il y a un pattern plus simple…

  • device => port => connexion <= port <= device

Ben oui, un device a des ports, chaque port peut avoir une connexion, et
une
connexion relie deux ports (qui de toute façon appartiennent chacun à un
device).

Bon, en AR::B ça donne quoi ?

class Device < AR::B
hm :ports
end

class Port < AR::B
bt :device
ho :connexion
end

class Connexion < AR::B
bt :port_src
bt :port_dst
end

En admettant que tu aies vraiment besoin d’un objet Connexion, ça me
semble
une solution possible. Mais laisse-moi t’en proposer une autre, dans le
cas
où l’objet Connexion ne serait utile qu’à faire le lien entre deux ports
:

class Device < AR::B
hm :ports
end

class Port < AR::B
bt :device
ho :port
end

Plus simple, plus élégant (après tout, un port ne peut être relié qu’Ã
une
seule connexion si on est dans le cas d’une liaison type réseau
informatique), plus maintenable (un modèle superflu de moins), et même
si le
modèle Connexion contanait des informations il est probable qu’elles
aient
été en doublon avec celles de “Port” par exemple (ex : vitesse de la
connexion, qui peut se déduire de la vitesse des deux ports).

Bon, c’est en admettant que j’ai compris le problème…

Michel B.

Bonjour Michel,
Merci d’avoir répondu et désolé de répondre aussi tard.
J’ai bien compris ton explication, mahleureusement mon modèle est plus
compliqué.
Ce que j’appelle une connexion est quelquechose de virtuel qui passe Ã
travers plusieurs équipements/ports.
Par exemple, sur un réseau “simple” :
|eqtA| – |eqtB| – |eqtC| – |eqtD|

On peut avoir une connexion qui va de A Ã D et une autre de B Ã C
Donc le lien du milieu, les ports de ce lien ont plusieurs connexions
qui passent.
Donc on a pas de relation has_one entre un port et une connexion.

De plus, une connexion peut passer plusieurs fois par le même équipement
et il faut le noter…

J’ai donc fait une relation has_many :through et ça marche bien

merci en tout cas pour ta réponse !

Sylvain