2010-08-03 2 views
13

quelqu'un pourrait me diriger vers la droite:rails plusieurs à plusieurs auto se joindre

J'essaie de construire un modèle de rails qui construisent le suivant:

ClassA -id

ClassA a une relation avec plusieurs "ClassA" (donc c'est une référence à lui-même)

Je cherche la migration et le modèle.

Je ne sais pas ce que un correct table de jointure (je pense que son simple table de 2 colonnes ClassA_id, ClassARel_ID -> à la fois le point ClassA) et comment construire le modèle

Merci!

+1

Pouvez-vous nous donner un exemple concret? Est-ce comme un humain qui a un parent (qui est évidemment un humain aussi)? Ou voulez-vous dire "Cars.all.green" pour renvoyer toutes les voitures vertes? –

+1

Oui, c'est comme Personne a beaucoup d'amis (Personnes) – awex

Répondre

29

j'utiliser quelque chose comme

class Person < ActiveRecord::Base 
    has_many :friendships, :foreign_key => "person_id", 
     :class_name => "Friendship" 

    has_many :friends, :through => :friendships 
end 

class Friendship < ActiveRecord::Base 
    belongs_to :person, :foreign_key => "person_id", :class_name => "Person" 
    belongs_to :friend, :foreign_key => "friend_id", :class_name => "Person" 
end 

Et les tables ressemblerais

people: id; name; whatever-you-need  
friendships: id; person_id; friend_id 
+0

merci, juste une question pour comprendre le fond: comment les rails savent que appartient à: ami,: foreign_key => "friend_id",: class_name => "Personne" est défini dans la table des amitiés (le champ friend_id)? – awex

+0

Je ne suis pas sûr d'avoir compris votre question. Comme nous pouvons le lire dans railsapi.com, "le mappage qui lie une classe Active Record donnée à une certaine table de base de données se fera automatiquement dans la plupart des cas". Et c'est le cas ici, à cause des noms de classe et de table. –

+3

Je ne sais pas pourquoi cela n'a pas été accepté. Est une très bonne réponse. Je dois essayer ceci et je verrai s'il se comporte comme prévu. – Amala

13

Si elle ne fait pas trop de sens pour créer une autre classe pour joindre les deux, une approche alternative pourrait être:

class Word < ActiveRecord::Base 
    has_and_belongs_to_many :synonyms, class_name: "Word", 
            join_table: "word_synonyms", 
            association_foreign_key: "synonym_id" 
end 

La table de jointure ressemblerait à ceci:

create_table :word_synonyms do |t| 
    t.integer :word_id 
    t.integer :synonym_id 
end 
0

de Malheureusement siffleur la réponse pourrait ne pas convenir dans de nombreux cas. Par exemple, cela ne fonctionne pas dans les deux sens. Par exemple, supposons que vous créez un nouveau mot:

word = Word.create(:word_name => 'tremble') 
['shake', 'vibrate'].each { |syn| word.synonyms.create(:word_name => syn) } 

Maintenant, si vous faites:

word = Word.find_by_word_name('tremble') 
p word.synonyms # this would print out the Words with the word_name 'shake' and 'vibrate'. 

cependant si vous l'avez fait l'inverse:

word = Word.find_by_word_name('vibrate') 

p word.synonyms # this would print an empty association. 

Cette dit que le mot «vibrer» n'a AUCUN synonymes.

Donc, fondamentalement, cette méthode ne fonctionnera pas dans les deux sens (par exemple vibrent est synonyme tremblent, et ils tremblent est synonyme de vibrent)

Edit: Dans un sens, vous pouvez utiliser cette approche, cependant, vous devrez attribuer explicitement les synonymes pour chaque mot. Donc, bien que vous ayez spécifié des synonymes de tremblement (qui sont 'vibrer' et 'secouer'), vous devrez toujours spécifier les synonymes de 'secouer' ('qui tremblent' et 'vibrer') et 'vibrer' (qui sont ' trembler 'et secouer').

Questions connexes