Rayların geçişi: t. Alternatif isimli referanslar?


121

Bu yüzden Okuldaki Kurslar için bunun gibi bir create_table'ım var:

create_table :courses do |t|
  t.string :name
  t.references :course
  t.timestamps
end

ancak aşağıdaki gibi diğer iki kursa referans vermesini istiyorum:

has_many :transferrable_as # A Course
has_many :same_as          # Another Course

Aşağıdakileri söyleyebilir miyim?

t.references :transferrable_as, :as=> :course

Yanıtlar:


161

Tüm bunları ilk geçiş / sütun tanımında yapabilirsiniz (en azından şu anda Rails 5'te):

t.references :transferable_as, index: true, foreign_key: {to_table: :courses}
t.references :same_as, index: true, foreign_key: {to_table: :courses}

10
Bu, Rails 5.1'de çalışır ve diğer önerilerin hiçbiri çalışmaz. Çok daha temiz ve doğru geliyor.
stephenmurdoch

2
Rails 5.1.4 kullanıyorum ama çalışmıyor. foreign_keyTablo oluşturmada bu şekilde bir seçenek belirttiğimde , oluşturduğum tablonun mevcut olmadığını söyleyen bir hata ortaya çıkıyor ... Bu yüzden resmi API tarafından gerçekten desteklenmediğinden şüpheleniyorum.
2017,


98

Bunu şu şekilde yapabilirsiniz:

create_table :courses do |t|
  t.string :name
  t.references :transferrable_as
  t.references :same_as
  t.timestamps
end

veya t.belongs_totakma ad olarak kullanmakt.references

Bu foreign_key: trueiki referans satırına ekleme yapamazsınız . Bunları veritabanı düzeyinde yabancı anahtar olarak işaretlemek istiyorsanız, bununla bir geçiş yapmanız gerekir:

add_foreign_key :courses, :courses, column: :transferrable_as_id
add_foreign_key :courses, :courses, column: :same_as_id

Güncelleme

Rails 5.1 ve üzeri sürümlerde yabancı anahtarı create_tablebloktaki geçişe şu şekilde ekleyebilirsiniz :

create_table :courses do |t|
  t.string :name
  t.references :transferrable_as, foreign_key: { to_table: 'courses' }
  t.references :same_as, foreign_key: { to_table: 'courses' }
  t.timestamps
end

5
foreign_key: trueReferans satırlarına ekleyememekle ilgili kısım beni heyecanlandıran şeydi. add_foreign_keyBunlar için sütun adını eklemek ve belirlemek hile yaptı.
Matthew Clark

Bu, Rails'de kutunun dışında çalışıyor mu? Stackoverflow.com/a/22384289/239657'ye göre , bu değerli schema_plustaş gerektirir . Rails'in add_reference belgeleri a: referanslar seçeneklerinden bahsetmez.
Beni Cherniavsky-Paskin

1
references:Seçeneğin ne için olduğunu takip etmiyorum (bunun aksine t.references, yabancı_key ile ilgili hususların halledilmesi ile bu yalnızca model düzeyinde geçerli olmaz mıydı add_foreign_key?
MCB

1
@MCB t.references, "bu tabloya başka bir tablonun birincil anahtarı olan bir alan ekle" diyor. references:Seçenek bir birincil anahtar (o alanın adıyla temizlemek değilse tabi) olan masa o söyler. add_foreign_keyBuradaki görevi yürütür başvuru bütünlüğü için veritabanını söyler.
Toby 1 Kenobi

2
@MCB bunca zaman sonra, her zaman haklı olduğunu anladım. Yukarıdaki ilk yorumunuz tam olarak doğru - add_foreign_keysatırlar veritabanına neyin yabancı anahtarın ne olduğunu bildirmeye özen gösterir. references:Parametre hiçbir şey yapmıyor.
Toby 1 Kenobi

13

Bu iş parçacığının daha farklı bir Rails-ish yolu olduğunu düşünüyorum: Scaffolding ActiveRecord: aynı veri türünden iki sütun

Göçte:

t.belongs_to: aktarılabilir_as

t.belongs_to: same_as


1
ancak db tabloyu hangi yabancı anahtara bağlayacağını nasıl biliyor? Bunu Postgres veritabanı ile deniyorum ve PG::UndefinedTable: ERRORvar olmayan bir tabloya yabancı anahtar kısıtlaması eklemeye çalışırken bana bir hata veriyor .
Toby 1 Kenobi

Herhangi birinin merak etmesi durumunda belongs_to, sadece bir takma addırreferences ve bu yüzden aynı işlevselliğe sahiptir.
Jason Swett

11

Bu soruya ek bir cevap olarak - Model ilişkilendirmeyi tamamlamak için aşağıdaki satıra sahip olmalıdır:

    belongs_to :transferrable_as, class_name: "Course"
    belongs_to :same_as, class_name: "Course"

3

Seçeneği referenceskabul ettiğini sanmıyorum :as, ancak sütunlarınızı manuel olarak oluşturabilirsiniz ...

create_table :courses do |t| 
  t.string  :name 
  t.integer :course1_id
  t.integer :course2_id 
  t.timestamps 
end 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.