Từ tài liệu về Rails 5.0 và tuyệt vời.
Guide
Bi-directional Hội
Đó là bình thường đối với các hiệp hội để làm việc theo hai hướng, đòi hỏi phải khai trên hai mô hình khác nhau:
class Author < ApplicationRecord
has_many :books
end
class Book < ApplicationRecord
belongs_to :author
end
Theo mặc định, Active Record doesn' t biết về kết nối giữa các liên kết này. Điều này có thể dẫn đến hai bản sao của một đối tượng nhận ra đồng bộ:
a = Author.first
b = a.books.first
a.first_name == b.author.first_name # => true
a.first_name = 'Manny'
a.first_name == b.author.first_name # => false
Điều này xảy ra bởi vì a và b.author hai cơ quan đại diện khác nhau trong bộ nhớ của cùng một dữ liệu, và không ai được tự động làm mới từ những thay đổi để cai khac. Active Record cung cấp: Tùy chọn inverse_of để bạn có thể thông báo cho nó những quan hệ:
class Author < ApplicationRecord
has_many :books, inverse_of: :author
end
class Book < ApplicationRecord
belongs_to :author, inverse_of: :books
end
Với những thay đổi này, Active Record sẽ chỉ tải một bản sao của đối tượng tác giả, ngăn chặn mâu thuẫn và làm cho ứng dụng của bạn hiệu quả hơn:
a = Author.first
b = a.books.first
a.first_name == b.author.first_name # => true
a.first_name = 'Manny'
a.first_name == b.author.first_name # => true
có một vài hạn chế đối với inverse_of hỗ trợ:
Họ không làm việc với: thông qua các hiệp hội. Chúng không hoạt động với: các hiệp hội đa hình. Chúng không hoạt động với: như các liên kết.
Đối với các liên kết thuộc đối tượng, các liên kết nghịch đảo has_many bị bỏ qua. Mọi liên kết sẽ tìm cách tự động tìm liên kết nghịch đảo và đặt tùy chọn: inverse_of theo phương pháp heuristically (dựa trên tên liên kết). Hầu hết các liên kết có tên chuẩn sẽ được hỗ trợ.Tuy nhiên, các hiệp hội có chứa các tùy chọn sau đây sẽ không có phần tử nghịch đảo của họ thiết lập tự động:
- : Điều kiện
- : thông qua
- : đa hình
- : foreign_key
Bạn có hiểu nhận xét trong tài liệu: "đối với các liên kết thuộc đối tượng has_many các liên kết nghịch đảo bị bỏ qua". Tuy nhiên, doc sử dụng ví dụ chính xác đó. Tôi đang thiếu gì ở đây? – dynex
Tôi không hoàn toàn chắc chắn. 'inverse_of' đã không thực sự nhìn thấy rất nhiều sử dụng vì vậy nó có thể là một hành vi đó không phải là rất tốt được xác định. Tôi đã thử sử dụng nó sau khi bạn chỉ ra rằng tính năng và nó đã không thực sự làm bất cứ điều gì hữu ích cho tôi. – tadman
Điều này rất lạ đối với tôi, bởi vì dường như với tôi rằng bạn sẽ luôn muốn hành vi này theo mặc định, và chỉ cần sử dụng: inverse_of khi không thể suy ra tên hiệp hội. Ngoài ra những mâu thuẫn trong định nghĩa là khó chịu, nhưng nó đã giúp tôi trong một vài trường hợp. Bất kỳ lý do gì tôi không nên chỉ dính nó ở khắp mọi nơi? – Ibrahim