Association plusieurs-à-plusieurs au même modèle avec ActiveRecord?
-
06-07-2019 - |
Question
Je suis ce tutoriel. qui fonctionne à merveille pour has_many: à travers les relations. J'ai des choses normales comme category_product qui fonctionne.
Cependant, je ne suis pas en mesure de conceptualiser cette situation (ni de la faire fonctionner): j'ai une catégorie qui a des catégories connexes. Étant donné que chaque catégorie peut avoir N catégories ... tout d’abord, s’agit-il d’une situation plusieurs-plusieurs (je suis assez sûr que ce soit le cas)? Deuxièmement, à quoi cela ressemblerait-il? Ma migration ressemble à ceci:
create_table :categories do |t|
t.string :name
t.timestamps
end
create_table :related_categories, :id => false do |t|
t.integer :category_a_id
t.integer :category_b_id
end
et les tripes de mon modèle sont
has_many :related_categories, :foreign_key=>"category_a_id"
has_many :categories, :through => :related_categories, :source=>:category_a
Ceci n’est évidemment pas correct, bien que cela y aboutisse (c’est-à-dire qu’il soit cassé à 100%). Comment puis-je faire cela?
Modifier: j'ai oublié cela, mais uniquement ici sur SO (ce qui signifie que ce n'est pas la réponse):
class RelatedCategory < ActiveRecord::Base
belongs_to :category_a, :class_name=>"Category"
belongs_to :category_b, :class_name=>"Category"
end
La solution
Vous devriez essayer : source = > : category_b
dans votre déclaration has_many.
Vous avez déjà utilisé category_a_id
en tant que clé étrangère de la table des catégories associées. Cela indique essentiellement à ActiveRecord de faire correspondre le champ category_a_id
de la table related_categories
avec l'ID d'objet Category actuel lors de l'extraction de tous les enregistrements related_categories qui lui sont associés. Le paramètre source de cette déclaration has_many: through
spécifie quel champ doit être pris en compte pour la recherche (ou l'écriture des objets associés) lors du remplissage de la collection de catégories.
Autres conseils
Voici la réponse, mais ce n’est pas beau.
has_many :related_categories, :foreign_key=>"category_a_id"
has_many :related_categories2, :class_name=>"RelatedCategory", :foreign_key=>"category_b_id"
has_many :categories, :through => :related_categories, :source=>:category_b
has_many :categories_backwards, :through => :related_categories2, :source=>:category_a
has_many :category_products
alors vous devriez faire un goofy getter qui combine les catégories + categories_backwards, ou quelque chose comme ça.
Modifier [2 minutes plus tard]: Wow, avec le getter, cela semble presque parfait! Bien sûr, le problème est que vous devez pousser aux catégories et pas à ce que vous obtenez de la part du getter.