Chỉ định tên cột trong một tài liệu tham khảo trên mạng


124

Tôi muốn tạo một migrationRails, tham khảo một bảng khác. Thông thường, tôi sẽ làm một cái gì đó như:

add_column :post, :user, :references

Điều này tạo ra một cột có tên user_idtrong postsbảng. Nhưng nếu, thay vì user_id, tôi muốn một cái gì đó như thế author_idnào? Làm thế nào tôi có thể làm điều đó?

Câu trả lời:


59

Làm thủ công:

add_column :post, :author_id, :integer

nhưng bây giờ, khi bạn tạo câu lệnh poss_to, bạn sẽ phải sửa đổi nó, vì vậy bây giờ bạn phải gọi

def post
    belongs_to :user, :foreign_key => 'author_id'
end

1
Tôi không phải thêm bất kỳ chỉ mục?
caarlos0

1
Có, bạn sẽ cần tạo một chỉ mục trong quá trình di chuyển.
Tom Harrison

1
Rails cheat - nó không thực sự sử dụng các chỉ mục theo mặc định. Bây giờ nếu bạn muốn lập chỉ mục (đó là một ý tưởng tuyệt vời - mặc dù thực tế là đường ray sẽ hoàn toàn bỏ qua chúng), hơn là bạn chắc chắn có thể thêm chúng. Bạn sẽ muốn xem hướng dẫn tôi liên kết để biết thêm thông tin về việc di chuyển nói chung và thậm chí bạn có thể kết thúc việc gọi mã SQL trực tiếp trong quá trình di chuyển của mình. Tôi sẽ nói bỏ qua nó, vì nó không phải là một phần bình thường của đường ray, bạn sẽ nhận được 0 hiệu suất từ ​​nó, vì các truy vấn SQL được tạo mặc định của rails không tận dụng lợi thế của nó. liên kết
mschultz

hmm hiểu. Cảm ơn rât nhiều!
caarlos0

sử dụng schema_plusđá quý, t.references :category, index: true, foreign_key: true, references: :match_categoriescũng làm việc cho tôi trong tập tin di chuyển.
elquimista

251

Đối với đường ray 5+

Định nghĩa ban đầu:

Nếu bạn đang định nghĩa của bạn Postbảng mô hình, bạn có thể thiết lập references, indexforeign_keytrong một dòng:

t.references :author, index: true, foreign_key: { to_table: :users }

Cập nhật hiện có:

Nếu bạn đang thêm các tham chiếu đến một bảng hiện có, bạn có thể làm điều này:

add_reference :posts, :author, foreign_key: { to_table: :users }

Lưu ý: Giá trị mặc định indexlà đúng.


Định nghĩa ban đầu sẽ cho phép null? Nếu không, bạn có biết sự thay thế nullable?
Vorpulus Lyphane

5
Định nghĩa này cho phép nulls. Để không cho phép chúng, hãy thêm tùy chọn thông thường null: false.
Ashitaka

Cảm ơn. Đối với "Định nghĩa ban đầu", tôi nghĩ "chỉ số: đúng" là không cần thiết. Tôi nhận được cùng một thay đổi lược đồ có hoặc không có nó. Đừng bận tâm; chỉ thấy ghi chú của bạn ở cuối
Joey

Cảm ơn, đây là những gì tôi đang tìm kiếm!
Philippe B.

250

Trong Rails 4.2+, bạn cũng có thể đặt khóa ngoại trong db, đây là một ý tưởng tuyệt vời .

Đối với các hiệp hội đơn giản, điều này cũng có thể được thực hiện khi t.referencesthêm foreign_key: true, nhưng trong trường hợp này bạn sẽ cần hai dòng.

# The migration
add_reference :posts, :author, index: true
add_foreign_key :posts, :users, column: :author_id

# The model
belongs_to :author, class_name: "User"

2
Cảm ơn, nhưng câu hỏi được gắn thẻ Rails3, tôi rất vui khi được giúp đỡ
ecoologic 17/2/2016

2
Ồ, tôi không nhận thấy điều đó. Vâng, nó rất hữu ích cho tôi. :)
bonh

2
Tôi gần như đã từ bỏ hy vọng khi nhìn thấy điều này! Cảm ơn bạn @ecoologic!
Dan Williams

2
@ecoologic, chỉ cần một điều bạn có thể muốn thêm, add_forign_key chỉ là rails 4.2+. ;)
Dan Williams

4
Tôi không chắc bạn cần references: :userstùy chọn trong add_referencecuộc gọi. Tôi không thấy nó được ghi lại trong các tài liệu và nó dường như hoạt động với mục đích của tôi mà không có nó.
jakecraige

87

Trong rails 4, khi sử dụng postgresql và lược đồ gem_plus bạn chỉ có thể viết

add_reference :posts, :author, references: :users

Điều này sẽ tạo ra một cột author_id, trong đó tham khảo chính xác users(id).

Và trong mô hình của bạn, bạn viết

belongs_to :author, class_name: "User"

Lưu ý, khi tạo một bảng mới, bạn có thể viết nó như sau:

create_table :things do |t| 
  t.belongs_to :author, references: :users 
end 

Lưu ý: toàn bộ schema_plusđá quý không tương thích với đường ray 5+, nhưng chức năng này được cung cấp bởi lược đồ đá quý_auto_forign_keys (một phần của lược đồ_plus) tương thích với đường ray 5.


28
và nếu bạn đang sử dụng create_table:t.references :author, references: :users
Michael Radionov

2
Thêm bình luận của @ MichaelRadionov vào câu trả lời của bạn sẽ làm cho nó hoàn hảo.
toxaq

2
Tôi đã xem xét nguồn Rails 4.1 và tôi không thể tìm thấy bất kỳ bằng chứng nào :referencesthực sự làm được gì cả.
jes5199

1
Vâng, bạn đã đúng, tôi đã sử dụng schema_plusđá quý từ lâu và nó thực sự bổ sung chức năng đó. Tôi chỉnh sửa câu trả lời của tôi cho phù hợp.
nathanvda

2
Trong Rails 6, có vẻ như cú pháp t.references :col_name, references: other_table_namehoạt động mà không cần cài đặt thêm đá quý.
Qqwy

51

Nếu bạn không sử dụng khóa ngoại, thì tên bảng thực tế của bảng kia là gì.

add_reference :posts, :author

Kể từ Rails 5 , nếu bạn đang sử dụng khóa ngoại, bạn có thể chỉ định tên của bảng khác trong các tùy chọn khóa ngoại. (xem https://github.com/rails/rails/issues/21563 để thảo luận)

add_reference :posts, :author, foreign_key: {to_table: :users}

Trước Rails 5, bạn nên thêm khóa ngoại như một bước riêng biệt:

add_foreign_key :posts, :users, column: :author_id

12
to_table là dạng số nhiều:{to_table: :users}
hoffmanc

-3

alias_attribution (new_name, old_name) rất tiện dụng. Chỉ cần tạo mô hình của bạn và mối quan hệ:

rails g model Post title user:references

sau đó chỉnh sửa mô hình và thêm một bí danh thuộc tính với

alias_attribute :author, :user

Sau đó, bạn sẽ có thể chạy những thứ như

Post.new(title: 'My beautiful story', author: User.first)

1
điều này không hoạt động khi bạn cần xác định nhiều tham chiếu đến một mô hình khác, ví dụ: bài đăng (tác giả, biên tập viên)
ultrajohn
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.