20

Ich habe eine harte Zeit herauszufinden, wie man eines meiner Modelle mit mehreren anderen zu verbinden.Schienen Modell, gehört zu vielen

So wie es jetzt ist, ich habe:

class ModelA < ActiveRecord::Base 
    has_many :model_b 
end 

class ModelB < ActiveRecord::Base 
    belongs_to :model_a 
end 

jedoch ... braucht Modell B zu gehören nicht nur eine Instanz von ModelA, aber vielleicht drei. Ich weiß, es gibt eine has_many: durch, aber ich bin mir nicht sicher, wie es in diesem Fall funktionieren würde. JEDE Instanz von ModelA wird immer genau drei Instanzen von ModelB haben. Aber wie bereits erwähnt, kann ModelB zu mehr als nur einer Instanz von ModelA gehören.

Antwort

40

Viele-zu-viele Beziehungen in Schienen verwenden nicht belongs_to. Stattdessen möchten Sie eine von mehreren Optionen verwenden. Die erste ist has_and_belongs_to_many:

# app/models/category.rb 
class Category < ActiveRecord::Base 
    has_and_belongs_to_many :items 
end 

# app/models/item.rb 
class Item < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
end 

Und Sie werden einen zusätzlichen Join-Tabelle in Ihrer Datenbank mit Migrations wie folgt hinzufügen müssen:

class AddCategoriesItems < ActiveRecord::Migration 
    def self.up 
    create_table :categories_items, :id => false do |t| 
     t.integer :category_id 
     t.integer :item_id 
    end 
    end 

    def self.down 
    drop_table :categories_items 
    end 
end 

Sie, dass der Name Join-Tabelle sehen kann, ist die Kombination der Namen der beiden anderen Tabellen. Die Tabellen müssen in alphabetischer Reihenfolge wie oben erwähnt werden, und die :id => false muss da sein, da wir keinen Primärschlüssel für diese Tabelle benötigen. Es wird den Schienenverband durchbrechen.

Es gibt auch eine andere, komplexere Methode, die als has_many :through bekannt ist, wenn Sie Informationen über die Beziehung selbst speichern müssen. Ich habe einen ganzen Artikel geschrieben beschreiben, wie beide Methoden zu tun, und wenn jeder verwenden:

Basic many-to-many Associations in Rails

Ich hoffe, das hilft, und kontaktieren Sie mich, wenn Sie Fragen haben! mit diesem

# app/models/category.rb 
class Category < ActiveRecord::Base 
    has_many :category_items 
    has_many :items, :through => :category_items 
end 

# app/models/item.rb 
class Item < ActiveRecord::Base 
    has_many :category_items 
    has_many :categories, :through => :category_items 
end 

# app/models/category_items.rb 
class CategoryItems < ActiveRecord::Base 
    belongs_to :category 
    belongs_to :items 
end 

Wenn Sie diese

+0

das war wirklich hilfreich! Eine nützliche Ergänzung wären einige Beispiele dafür, wie wir auf diese Beziehungen im Code zugreifen können (entweder in einem Controller oder in einer Ansicht) danke – msanjay

26

Dies ist, was @Jaime Bellmyer

# app/models/category.rb 
class Category < ActiveRecord::Base 
    has_and_belongs_to_many :items 
end 

# app/models/item.rb 
class Item < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
end 

verwendet würde ich empfehlen, verwenden müssen Sie ein Modell anschließen, die Ihnen mehr Kontrolle über Handling-Kategorie geben und Artikel. Aber mit dem, was @Jaime vorgeschlagen hat, haben Sie nur eine Join-Tabelle und kein Modell, das nicht unter Kontrolle ist.

+0

bedeutet dies, dass ich den Fremdschlüssel aus den Tabellen herausnehmen sollte, da sie von der Tabelle beitreten? – Edmund

+0

Ja. Sie müssen die Fremdschlüssel nicht in den übergeordneten Tabellen speichern, da diese im Join-Modell gespeichert werden können. – Rohit

+0

Warum ist es nicht ausreichend, einfach Kategorie has_many: items zu sagen (ein Objekt gehört zu vielen Kategorien, aber ActiveRecord hat das nicht) –