Bonjour à tous.
Contexte : je veux modéliser des bus de connection entre périphériques externes.
Je crée pour celà une table Buses :
class CreateBuses < ActiveRecord::Migration
def self.up
create_table :buses do |t|
t.column :name, :string
t.column :version, :string
t.column :speed, :integer
end
end
def self.down
drop_table :buses
end
end
Je veux pouvoir gérer la compatibilité entre les divers bus: par exemple je suppose qu'un bus SCSI1 est compatible avec un bus SCSI2. Je dois donc gérer une relation récursive sur ma table (un bus peut être compatible avec plusieurs autres bus) Cependant, lorsque j'ajoute un bus d'un certain type dans ma liste de compatibilité, il faut que la réciproque soit vraie (exemple : un bus SCSI2 est compatible avec SCSI1, et vice-versa. Notez que je ne parle pas de format de connecteur, je parle juste en terme de bus). Autrement dit, lorsque j'ajoute scsi2 à la liste des bus compatibles avec scsi1, je ne dois pas ajouter scsi1 à la liste des bus compatibles à SCSI2, c'est censé se faire tout seul.
Dans un premier temps, pour gérer la relation, j'ai créé une table buses_compatibles de la façon suivante :
class CreateBusesCompatibles < ActiveRecord::Migration
def self.up
create_table :buses_compatibles do |t|
t.column :bus_id, :integer
t.column :compatible_id, :integer
end
end
def self.down
drop_table :buses_compatibles
end
end
Puis je modifie mon modèle ainsi:
class Bus < ActiveRecord::Base
has_many :idiskslotmodels
has_and_belongs_to_many :compatibles,
:class_name=> "Bus",
:join_table => "buses_compatibles",
:association_foreign_key =>"compatible_id",
:foreign_key => "bus_id",
:after_add => :be_compatibly_to_compatible,
:after_remove => :no_more_compatible
def be_compatibly_to_compatible(compatible)
compatible.compatibles << self unless compatible.compatibles.include?(self)
end
def no_more_compatible(compatible)
compatible.compatibles.delete(self) rescue nil
end
end
Lorsque je crée un bus, et que j'ajoute des autres bus dans la liste des bus compatibles, ça se passe bien, mais c'est lorsque je sauve que j'ai un problème. J'ai l'impression que les bus demandent aux bus compatibles de se sauvegarder, et les bus compatibles font la même chose donc rappellent le bus "originel" qui lui rappelle la méthode de sauvegarde du bus compatible, etc ... et ce infiniment.
Ci-dessous un exemple :
Loading development environment.
>> b1=Bus.new
=> #nil, "version"=>nil, "speed"=>nil}>
>> b2=Bus.new
=> #nil, "version"=>nil, "speed"=>nil}>
>> b2.compatibles<
=> [#nil, "version"=>nil, "speed"=>nil}>], @new_record=t
rue, @attributes={"name"=>nil, "version"=>nil, "speed"=>nil}>]
>> b1.save
SystemStackError: stack level too deep
[... ]
Voyez-vous un moyen d'empêcher ça ?
Merci d'avance pour votre aide.
# Ce que j'ai constaté :
Posté par totof2000 . Évalué à 2.
# début de piste
Posté par totof2000 . Évalué à 3.
Je vais éplucher ça ...
# début de piste
Posté par totof2000 . Évalué à -1.
Je vais éplucher ça ...
# Donc
Posté par jhc_ . Évalué à 1.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.