menghasilkan model menggunakan pengguna: referensi vs user_id: integer

176

Saya bingung tentang cara membuat model yang menjadi milik model lain. Buku saya menggunakan sintaks ini untuk mengaitkan Micropost dengan Pengguna:

rails generate model Micropost user_id:integer

tetapi http://guides.rubyonrails.org/ mengatakan untuk melakukannya seperti ini:

rails generate model Micropost user:references

Migrasi yang dihasilkan oleh 2 ini berbeda. Juga, untuk yang pertama, bagaimana rel tahu itu user_idadalah referensi kunci asing user? Terima kasih!

stackOverlord
sumber

Jawaban:

190

Keduanya akan menghasilkan kolom yang sama saat Anda menjalankan migrasi. Di konsol rel, Anda dapat melihat bahwa ini masalahnya:

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

Perintah kedua menambahkan belongs_to :userhubungan dalam model Micropost Anda sedangkan yang pertama tidak. Ketika hubungan ini ditentukan, ActiveRecord akan mengasumsikan bahwa kunci asing disimpan di user_idkolom dan itu akan menggunakan model bernama Useruntuk instantiate pengguna tertentu.

Perintah kedua juga menambahkan indeks pada user_idkolom baru .

Jon M.
sumber
1
Apakah mungkin untuk menghasilkan model dengan referensi dari dua tabel
praveenkumar
Perhatikan bahwa itu tidak menambahkan asosiasi has_many pada model lain (pengguna), yang mungkin ingin Anda tambahkan juga.
Sv1
45

bagaimana rel tahu itu user_idadalah referensi kunci asing user?

Rails sendiri tidak tahu bahwa itu user_idadalah referensi kunci asing user. Dalam perintah pertama rails generate model Micropost user_id:integerhanya menambahkan kolom user_idnamun rel tidak tahu penggunaan col. Anda harus secara manual meletakkan garis dalam Micropostmodel

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

kata kunci belongs_todan has_manymenentukan hubungan antara model-model ini dan menyatakan user_idsebagai kunci asing untuk Usermodel.

Perintah selanjutnya rails generate model Micropost user:referencesmenambahkan baris belongs_to :userdalam Micropostmodel dan dengan ini menyatakan sebagai kunci asing.

FYI
Mendeklarasikan kunci asing menggunakan metode sebelumnya hanya membuat Rails tahu tentang hubungan model / tabel. Basis data tidak diketahui tentang hubungannya. Karena itu ketika Anda membuat Diagram EER menggunakan perangkat lunak seperti MySql WorkbenchAnda menemukan bahwa tidak ada thread hubungan yang ditarik antara model. Seperti pada gambar berikut masukkan deskripsi gambar di sini

Namun, jika Anda menggunakan metode yang lebih baru, Anda menemukan bahwa file migrasi Anda terlihat seperti:

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

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

Sekarang kunci asing diatur di tingkat basis data. dan Anda dapat menghasilkan EERdiagram yang tepat . masukkan deskripsi gambar di sini

pemain sulap
sumber
1
Tampaknya generator Rails terbaru menggantikan add_foreign_keyaksi dengan opsi foreign_key: trueke t.referencessaluran, yang menyiratkan index: true. Jadi sekarang t.references :user, foreign_key: true. Saat ini tidak ada dokumentasi untuk foreign_keyopsi yang tersedia, jadi ini hanya asumsi saya.
Franklin Yu
Oh, add_referencetindakan memiliki :foreign_keyopsi yang menambahkan batasan kunci asing yang sesuai . Saya kira opsi ini akan melakukan hal yang sama saat membuat tabel.
Franklin Yu
Bagaimana Anda mengekspor ruby ​​db ke meja kerja? dapatkah Anda menjawabnya di sini: stackoverflow.com/questions/42982921/…
Krawalla
Apakah memiliki add_foreign_key :microposts, :users perbedaan untuk Rails?
Linus
17

Untuk yang pertama, konvensi tentang konfigurasi. Rails default saat Anda mereferensikan tabel lain dengan

 belongs_to :something

adalah mencari something_id.

references, atau belongs_tosebenarnya cara penulisan yang lebih baru dengan beberapa kebiasaan.

Penting untuk diingat bahwa itu tidak akan membuat kunci asing untuk Anda. Untuk melakukan itu, Anda perlu mengaturnya secara eksplisit menggunakan:

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

atau (perhatikan bentuk jamak):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`
Krule
sumber
1
dapatkah Anda menjelaskan apa yang Anda maksudkan dengan mengatakan bahwa referensi tidak akan membuat kunci asing untuk Anda. Apa bedanya dengan perintah pertama menggunakan user_id: integer secara langsung?
shailesh
Tidak, kecuali jika Anda menggunakan :polymorphicopsi (yang IMHO, untuk sebagian besar kasus, bukan ide yang baik). Jika Anda ingin menggunakan kunci asing di ActiveRecord, gunakan orang asing .
Krule
1
@ Krule Now add_foreign_keytelah membuatnya menjadi ActiveRecord.
Franklin Yu