Có thể có nhiều mối quan hệ has_many :through
đi qua nhau trong Rails không? Tôi đã nhận được đề xuất làm như vậy là một giải pháp cho một câu hỏi khác mà tôi đã đăng, nhưng không thể làm cho nó hoạt động.Ruby-on-Rails: Nhiều has_many: thông qua có thể?
Bạn bè là liên kết cyclic thông qua bảng tham gia. Mục tiêu là tạo một has_many :through
cho friends_comments
, vì vậy tôi có thể chụp User
và làm một cái gì đó như user.friends_comments
để nhận tất cả các nhận xét của bạn bè trong một truy vấn.
class User
has_many :friendships
has_many :friends,
:through => :friendships,
:conditions => "status = #{Friendship::FULL}"
has_many :comments
has_many :friends_comments, :through => :friends, :source => :comments
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
end
Điều này có vẻ tuyệt vời và có ý nghĩa nhưng không hiệu quả đối với tôi. Đây là lỗi tôi nhận được một phần có liên quan khi tôi thử truy cập friends_comments của người dùng:
ERROR: column users.user_id does not exist
: SELECT "comments".* FROM "comments" INNER JOIN "users" ON "comments".user_id = "users".id WHERE (("users".user_id = 1) AND ((status = 2)))
Khi tôi chỉ cần nhập user.friends, mà làm việc, đây là truy vấn nó thực thi:
: SELECT "users".* FROM "users" INNER JOIN "friendships" ON "users".id = "friendships".friend_id WHERE (("friendships".user_id = 1) AND ((status = 2)))
Vì vậy, có vẻ như nó hoàn toàn quên đi bản gốc has_many
thông qua mối quan hệ hữu nghị, và sau đó là không thích hợp khi cố gắng sử dụng lớp Người dùng làm bảng kết nối.
Tôi có làm điều gì sai, hoặc điều này đơn giản là không thể?
Thật không may, mục đích ban đầu đằng sau phương pháp này là để tôi có thể nhận tất cả các bình luận của bạn bè từ SQL trong một truy vấn. Xem tại đây: http://stackoverflow.com/questions/2382642/ruby-on-rails-how-to-pull-out-most-recent-entries-from-a-limited-subset-of-a-dat Nếu tôi viết một hàm, điều đó sẽ dẫn đến một số truy vấn N + 1. –
Không, nó sẽ không. Nó sẽ là 2 truy vấn. Truy vấn đầu tiên để có được bạn bè và truy vấn thứ hai để nhận được các ý kiến cho ** tất cả ** bạn bè. Nếu bạn đã tải bạn bè vào mô hình người dùng thì bạn không phải chịu bất kỳ chi phí nào. Tôi đã cập nhật giải pháp với hai cách tiếp cận khác. Hãy xem. –
@williamjones Bạn không có vấn đề N + 1 trong cả ba cách tiếp cận. Bạn có thể kiểm tra tệp nhật ký của mình để đảm bảo điều này. Cá nhân tôi thích cách tiếp cận 1 vì nó khá thanh lịch, tức là 'user.friends.comments' tốt hơn' user.friends_comments' –