2010-10-22 25 views
11

İlişkilendirmeyi tanımlamak için has_and_belongs_to_many kullandığım çoktan fazla ilişkiye sahip iki tablo var.Birincil anahtar olmadan birleştirme tablosu oluşturma

class Foo < ActiveRecord::Base 
    ... 
    has_and_belongs_to_many :bar 
    ... 
end 

class Bar < ActiveRecord::Base 
    ... 
    has_and_belongs_to_many :foo 
    ... 
end 
Ben de sınıf tablo

class BarFoo < ActiveRecord::Base 
    ... 
    belongs_to :foo 
    belongs_to :bar 
    ... 
end 

Ben tırmık db çalıştırmak katılmak temsil etmek tanımladık

: tohum aşağıdaki hatayı alıyorum:

Primary key is not allowed in a has_and_belongs_to_many join table (bar_foo) 

Ben veritabanını düzenlerseniz ve birincil anahtar alanını (ID) bar_foo tablosundan çıkarın ve daha sonra rake db'yi çalıştırın: tohum her şey istenen şekilde çalışır.

Yukarıdakiler göz önüne alındığında, birincil anahtarsız raylarda birleştirme tabloları oluşturmak için tercih edilen araç nedir? ve bunun tersi ama "nil için tanımsız yöntem 'klass': NilClass" gibi bir hata mesajı şey var ": aracılığıyla =>: foo: barlar Has_many"

Ben de kullanarak çalıştı.

cevap

4

Eğer bunun için bir model oluşturmak gereken bir HABTM dernek kullanmak isterseniz - bar_id ve foo_id tamsayı sütunları ile bir masayı bars_foos. Eğer aradaki modeli gerekiyorsa (eğer created_at izini veya ilişki diğer bazı özelliklerini tutmak istiyorsanız mesela)

Eğer örneğin ek modelini ekleyebilir Barred ve sonra olurdu:

class Foo < ActiveRecord::Base 
    ... 
    has_many :bars, :through => :barred 
    ... 
end 

class Bar < ActiveRecord::Base 
    ... 
    has_many :foos, :through => :barred 
    ... 
end 

class Barred < ActiveRecord::Base 
    has_many :bars 
    has_many :foos 
end 
+0

Matt, yanıt için teşekkürler. RoR için nispeten yeniyim, bu yüzden karşılık gelen model dosyaları olmayan bir tablo yaratmanın tercih edilen yolu nedir? Bu sadece bir göç dosyası oluşturarak ve tabloyu iki öznitelik bar_id ve foo_id ile tanımlamak için create_table kullanarak yapılabilir mi? – Keith

+0

İşte nasıl yapılacağı ile ilgili güzel bir cevap: [HABTM birleştirme tablosu için el ile geçişi mi oluşturmalıyım?] (Http://stackoverflow.com/questions/564306/do-i-need-to-manually-create -a migrasyon için-a-habtm-ol-masa) – Matt

22

Evet, birincil anahtar has_and_belongs_to_many için izin verilmez.

bu tabloda birincil anahtar kaldırın:

Buna çözmek için 2 yol vardır. Taşıma sınıfında: bunun dışında

create_table :bar_foo, :id => false do |t| 
    t.integer :bar_id 
    t.integer :foo_id 
end 

, sen app/models dosyayı bar_foo.rb silin ve aynı zamanda oluşturulan olabilecek tüm demirbaş ve test dosyaları kaldırmak zorunda kalacaktır. Dosyaları yok etmek ve daha sonra geçişi yeniden oluşturmak için script/destroy (veya rails destroy) numaralı telefonu aramak iyi bir fikirdir. Sen has_and_belongs_to_many dernek bir tablo arayacaktır

class BarFoo < ActiveRecord::Base 
    ... 
    belongs_to :foo 
    belongs_to :bar 
    ... 
end 

modeli gerekmez has_many :through

class Foo < ActiveRecord::Base 
    ... 
    has_many :bar_foos 
    has_many :bars, :through => :bar_foos 
    ... 
end 

class Bar < ActiveRecord::Base 
    ... 
    has_many :bar_foos 
    has_many :foos, :through => :bar_foos 
    ... 
end 

class BarFoo < ActiveRecord::Base 
    ... 
    belongs_to :foo 
    belongs_to :bar 
    ... 
end 
3

için

Ya dönüştürmek Bir üretmek yapmanız gerekenleri veritabanınızda bar_foo denilen bu tabloyu oluşturmak için geçiş.

raylar göç add_table_bar_foo_for_association oluşturmak

o zaman göç düzenlemek ve bu Şimdi dernek çalışması gerekir ve ilişkilendirmeyi gerektiğinde de size katılmak ekstra özelliklerini sağlamak için bu

class AddTableBarFooForAssociation < ActiveRecord::Migration 
    def up 
    create_table :bar_foo, :id => false do |t| 
     t.references :bar 
     t.references :foo 
    end 
    end 

    def down 
    drop_table :bar_foo 
    end 
end 

gibi görünmelidir has_many :through yolunu kullanabilir ve bununla ilişkili bir model oluşturabilirsiniz.

İlgili konular