tạo mô hình bằng user: tham chiếu vs user_id: số nguyên


176

Tôi bối rối về cách tạo một mô hình thuộc về mô hình khác. Sách của tôi sử dụng cú pháp này để liên kết Micropost với Người dùng:

rails generate model Micropost user_id:integer

nhưng http://guides.rubyonrails.org/ nói hãy làm như thế này:

rails generate model Micropost user:references

Các di chuyển được tạo ra bởi 2 là khác nhau. Ngoài ra, đối với trước đây, làm thế nào để đường ray biết đó user_idlà một tham chiếu khóa ngoại user? Cảm ơn!

Câu trả lời:


190

Cả hai sẽ tạo cùng một cột khi bạn chạy di chuyển. Trong bảng điều khiển rails, bạn có thể thấy rằng đây là trường hợp:

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

Lệnh thứ hai thêm một belongs_to :usermối quan hệ trong mô hình Micropost của bạn trong khi lệnh thứ nhất thì không. Khi mối quan hệ này được chỉ định, ActiveRecord sẽ cho rằng khóa ngoại được giữ trong user_idcột và nó sẽ sử dụng một mô hình có tên Userđể khởi tạo người dùng cụ thể.

Lệnh thứ hai cũng thêm một chỉ mục trên user_idcột mới .


1
Có thể tạo một mô hình với các tham chiếu của hai bảng
Praveenkumar

Lưu ý rằng nó không thêm liên kết has_many trên mô hình (người dùng) khác mà bạn có thể muốn thêm vào.
Sv1

45

Làm thế nào để đường ray biết đó user_idlà một tham chiếu khóa nước ngoài user?

Bản thân Rails không biết đó user_idlà một tham chiếu khóa ngoại user. Trong lệnh đầu tiên, rails generate model Micropost user_id:integernó chỉ thêm một cột user_idtuy nhiên đường ray không biết việc sử dụng col. Bạn cần phải tự đặt dòng trong Micropostmô hình

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

các từ khóa belongs_tohas_manyxác định mối quan hệ giữa các mô hình này và khai báo user_idlà khóa ngoại đối với Usermô hình.

Lệnh sau rails generate model Micropost user:referencesthêm dòng belongs_to :usertrong Micropostmô hình và từ đây tuyên bố là khóa ngoại.

FYI
Khai báo các khóa ngoại bằng phương thức cũ chỉ cho Rails biết về mối quan hệ mà các mô hình / bảng có. Cơ sở dữ liệu chưa biết về mối quan hệ. Do đó, khi bạn tạo Sơ đồ EER bằng phần mềm như MySql Workbenchbạn thấy rằng không có luồng quan hệ nào được vẽ giữa các mô hình. Giống như trong hình sau nhập mô tả hình ảnh ở đây

Tuy nhiên, nếu bạn sử dụng phương pháp sau, bạn thấy rằng tệp di chuyển của bạn trông như sau:

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

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

Bây giờ khóa ngoại được đặt ở cấp cơ sở dữ liệu. và bạn có thể tạo EERsơ đồ thích hợp . nhập mô tả hình ảnh ở đây


1
Có vẻ như trình tạo Rails mới nhất đã thay thế add_foreign_keyhành động bằng một tùy chọn foreign_key: truecho t.referencesdòng, ngụ ý này index: true. Vì vậy, bây giờ nó là t.references :user, foreign_key: true. Hiện tại không có tài liệu cho foreign_keytùy chọn có sẵn, vì vậy đây chỉ là giả định của tôi.
Franklin Yu

Ồ, add_referencehành động có một :foreign_keytùy chọn thêm ràng buộc khóa ngoại thích hợp . Tôi đoán tùy chọn này sẽ làm tương tự khi tạo bảng.
Franklin Yu

Làm thế nào để bạn xuất db ruby ​​của bạn vào bàn làm việc? bạn có thể trả lời câu hỏi này ở đây không: stackoverflow.com/questions/42982921/iêu
Krawalla

add_foreign_key :microposts, :users làm cho bất kỳ sự khác biệt cho Rails?
Linus

17

Đối với trước đây, quy ước về cấu hình. Rails mặc định khi bạn tham chiếu một bảng khác với

 belongs_to :something

là để tìm kiếm something_id.

references, hoặc belongs_tothực sự là cách viết mới hơn trước đây với một vài quirks.

Quan trọng là hãy nhớ rằng nó sẽ không tạo khóa ngoại cho bạn. Để làm điều đó, bạn cần thiết lập nó một cách rõ ràng bằng cách sử dụng:

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

hoặc (lưu ý số nhiều):

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

1
bạn có thể giải thích ý của bạn là gì khi nói rằng các tài liệu tham khảo sẽ không tạo ra các khóa ngoại cho bạn. Nó khác với lệnh đầu tiên bằng cách sử dụng user_id: số nguyên trực tiếp như thế nào?
shailesh

Không, trừ trường hợp bạn đang sử dụng :polymorphictùy chọn (mà IMHO, trong hầu hết các trường hợp, không phải là ý kiến ​​hay). Nếu bạn muốn sử dụng khóa ngoại trong ActiveRecord, hãy sử dụng người nước ngoài .
Krule

1
@Krule Bây giờ add_foreign_keyđã biến nó thành ActiveRecord.
Franklin Yu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.