2009-02-19 5 views
77

Ich habe Probleme, HATBM richtig zu machen. Ich habe eine geschlagene scanario: Artikel und Tags. Ich nehme an, HABTM sollte hier verwendet werden, da es eine Viele-zu-Viele-Beziehung ist. Ich weiß aber nicht, ob ich manuell eine Join-Tabelle erstellen soll (articles_tags in diesem Fall).Muss ich manuell eine Migration für eine HABTM Join-Tabelle erstellen?

Mein Code derzeit wie folgt:

class Article < ActiveRecord::Base 
    has_and_belongs_to_many :tags 
end 

class Tag < ActiveRecord::Base 
    has_and_belongs_to_many :articles 
end 

Wenn ich die Migration ausführen, keine dritte Tabelle erstellt wird. Auch möchte ich hinzufügen, dass meine dritte Tabelle keine Domain-Logik, nur blinde Zuordnung trägt.

Ich bin mit Rails 2.2.2

+1

Selbst bei Schienen 4, ich denke, die Antwort darauf ist .... "Ja"? :( – dtc

+1

@ dtc, immer noch ja, immer noch wahr. – Valentin

Antwort

140

Sie sollten dies von einem der Tische in einer Migration tun, oder in einer separaten Migration, wenn diese Migrationen RAN waren:

create_table :articles_tags, :id => false do |t| 
    t.references :article, :tag 
end 

add_index :articles_tags, [:article_id, :tag_id] 

Dieser Wille Erstellen Sie die Tabelle für Sie, und die :id => false weist Rails an, dieser Tabelle kein ID-Feld hinzuzufügen. Es gibt auch einen Index, der die Suche nach dieser Join-Tabelle beschleunigt.

Sie könnten auch ein Modell (ArticlesTag) für diesen und erzeugen:

# article.rb 
has_many :articles_tags 
has_many :tags, :through => :articles_tags 

# tag.rb 
has_many :articles_tags 
has_many :articles, :through => :articles_tags 

# article_tag.rb 
belongs_to :tag 
belongs_to :article 

Und dann die Tabelle in der von dem script/generate model articles_tag Aufruf erzeugt Migration erstellen.

+0

Danke, Radar, das ist, was ich brauchte! – Valentin

+12

Lustig, dass offizielle Führer oder Dokumentation nicht das. Ich musste auf Stackoverflow graben. Ty. – lzap

+0

Was wäre, wenn Sie sie mit einem eindeutigen Namen für den Join verknüpfen möchten, da dieser Join bereits verwendet wurde? – Trip

7

Sie wahrscheinlich auch einen Index für die Migration hinzufügen möchten:

add_index "articles_tags", "article_id"

add_index "articles_tags", "tag_id"

Wenn Sie jedoch Tagging wollen Funktionalität würde ich die acts_as_taggable_on Schienen-Plugin empfehlen:

http://www.intridea.com/tag/acts_as_taggable_on http://github.com/mbleigh/acts-as-taggable-on/

Ich habe es in einem Projekt verwendet und es war sehr einfach zu implementieren.

Eines der Probleme mit einer Join-Tabelle zum Tagging ist, dass es leicht hässlich werden kann, eine Join-Tabelle für jeden Inhaltstyp zu erstellen, den Sie taggable machen möchten (zB comments_tags, posts_tags, images_tags, etc). Dieses Plugin verwendet eine Taggingtabelle, die einen Diskriminator enthält, um den Inhaltstyp zu bestimmen, ohne dass für jeden Typ eine spezifische Join-Tabelle benötigt wird.

+0

Migrationsmethodenreferenzen (oder belongs_to) fügt automatisch Indizes hinzu. Du brauchst das nicht. Sie können damit Ihre Migration unterbrechen. – lzap

+0

Referenzen auf Migrationsmethoden (oder belongs_to) fügen Indizes nicht automatisch hinzu. (Dachte sie tun :-) – lzap

+0

IMHO wäre es besser, einen zusammengesetzten Primärschlüssel zu erstellen. Aber es ist datenbankspezifisch. –

Verwandte Themen