user: reference vs user_id: integer kullanarak model üret


177

Başka bir modele ait bir modelin nasıl oluşturulacağı konusunda kafam karıştı. Kitabım, Micropost'u Kullanıcı ile ilişkilendirmek için bu sözdizimini kullanır:

rails generate model Micropost user_id:integer

ancak http://guides.rubyonrails.org/ bunu şöyle yaptığını söylüyor:

rails generate model Micropost user:references

Bu 2 tarafından oluşturulan göçler farklıdır. Ayrıca, birincisi için, raylar bunun user_idyabancı bir anahtar referansı olduğunu nasıl biliyor user? Teşekkürler!

Yanıtlar:


190

Taşıma işlemini çalıştırdığınızda her ikisi de aynı sütunları oluşturur. Raylar konsolunda, durumun böyle olduğunu görebilirsiniz:

:001 > Micropost
=> Micropost(id: integer, user_id: integer, created_at: datetime, updated_at: datetime)

İkinci komut belongs_to :userMicropost modelinize bir ilişki eklerken, birincisi eklemez. Bu ilişki belirtildiğinde, ActiveRecord yabancı anahtarın user_idsütunda tutulacağını varsayar ve Usersöz konusu kullanıcıyı örneklemek için adlandırılmış bir model kullanır .

İkinci komut ayrıca yeni user_idsütuna bir dizin ekler .


1
İki tablonun referanslarıyla bir model oluşturmak mümkün mü
praveenkumar

Diğer modele (kullanıcı) da eklemek isteyebileceğiniz bir has_many ilişkilendirmesi eklemediğini unutmayın.
Sv1

45

raylar bunun user_idyabancı anahtar referansı olduğunu nasıl bilir user?

Rayların kendisi user_idbunun yabancı bir anahtar referansı olduğunu bilmiyor user. İlk komutta rails generate model Micropost user_id:integersadece bir sütun ekler, user_idancak raylar col kullanımını bilmez. Çizgiyi Micropostmodele manuel olarak koymanız gerekir

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

anahtar kelimeler belongs_tove has_manybu modeller arasındaki ilişkiyi belirlemek ve model user_idiçin yabancı bir anahtar olarak ilan User.

Sonraki komut , modeli modele rails generate model Micropost user:referencesekler ve böylece yabancı anahtar olarak bildirir.belongs_to :userMicropost

FYI
Yabancı anahtarların eski yöntemi kullanarak bildirilmesi, Rayların sadece modellerin / tabloların ilişkisi hakkında bilgi sahibi olmasını sağlar. Veritabanı ilişki hakkında bilinmiyor. Bu nedenle, EER Diyagramlarını MySql Workbenchsizin gibi bir yazılım kullanarak oluşturduğunuzda , modeller arasında ilişki ilişkisi çizilmediğini göreceksiniz. Aşağıdaki resimdeki gibi resim açıklamasını buraya girin

Ancak, sonraki yöntemi kullanırsanız, taşıma dosyanızın aşağıdaki gibi olduğunu görürsünüz:

def change
    create_table :microposts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :microposts, :users

Şimdi yabancı anahtar veritabanı düzeyinde ayarlanmıştır. ve uygun EERdiyagramlar oluşturabilirsiniz . resim açıklamasını buraya girin


1
Görünüşe göre en son Rails jeneratörü, add_foreign_keyeylemi ima foreign_key: trueeden t.referenceshatta bir seçenekle değiştirdi index: true. Yani şimdi t.references :user, foreign_key: true. Şu anda mevcut foreign_keyseçenek için herhangi bir belge yok , bu yüzden bu sadece benim varsayımım.
Franklin Yu

Ah, add_referenceeylem bir sahiptir :foreign_keyseçeneği uygun bir yabancı anahtar kısıtlaması ekleyin . Sanırım bu seçenek tablo oluştururken de aynısını yapardı.
Franklin Yu

Ruby db'nizi çalışma tezgahına nasıl ihraç edersiniz? belki burada cevap verebilir misiniz: stackoverflow.com/questions/42982921/…
Krawalla

Sahip mu add_foreign_key :microposts, :users Raylar için herhangi bir fark?
Linus

17

İlki için yapılandırma konvansiyonu. İle başka bir tabloya başvurduğunuzda varsayılan raylar

 belongs_to :something

aramaktır something_id.

referencesya belongs_toda aslında bir kaç tuhaflık ile eskisini yazmanın daha yeni bir yoludur.

Önemli olan, sizin için yabancı anahtarlar oluşturmayacağını hatırlamaktır. Bunu yapmak için, aşağıdakilerden birini kullanarak açıkça ayarlamanız gerekir:

t.references :something, foreign_key: true
t.belongs_to :something_else, foreign_key: true

veya (çoğullara dikkat edin):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`

1
referansların sizin için yabancı anahtar oluşturmayacağını söyleyerek ne demek istediğinizi açıklayabilir misiniz? User_id: integer komutunu doğrudan kullanan ilk komuttan farkı nedir?
shailesh

:polymorphicSeçeneği kullanmanız dışında (çoğu durumda IMHO iyi bir fikir değildir) değildir. ActiveRecord'da yabancı anahtarları kullanmak istiyorsanız, foreigner kullanın .
Krule

1
@Krule Now add_foreign_key, ActiveRecord'a girdi.
Franklin Yu
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.