2012-11-15 51 views
9

Tôi đang cố gắng tối ưu hóa truy vấn của mình trên trang web của mình.tham gia lồng nhau sâu trong activerecord

Tôi có 3 mô hình, hình ảnh, Person, Appearances

xuất hiện hình ảnh has_many, và nhiều người thông qua sự xuất hiện Xuất hiện bảng chỉ có một Person_Id, photo_id

Bây giờ, nếu tôi được làm một tìm kiếm trên một 'người' và tôi muốn tải háo hức xuất hiện và hình ảnh của họ, tôi sẽ làm một cái gì đó như thế này:

Person.joins(:appearances => :photo).limit(5) 

Bây giờ, tôi không chắc chắn nếu điều này là lý tưởng, nhưng giả thuyết người của tôi có xuất hiện mà thuộc về một bức ảnh, lần lượt xuất hiện và những người khác. Tôi thậm chí không biết liệu bạn có muốn làm điều này trong vanilla SQL hay không, nhưng tôi chỉ tò mò nếu điều này là có thể.

Person.joins(:appearances => :photo => :appearaces => :person).limit(5) 

Cú pháp này kết quả trong lỗi, một lần nữa, tôi chỉ tò mò, tôi đang xử lý nhận được sự xuất hiện và nhân dân một bức ảnh bên trong quan điểm của tôi, tôi chỉ muốn thử nghiệm với thời gian tải và xem nếu điều này là thậm chí có thể.

Trả lời

11

Để tải "mong muốn", bạn sử dụng .include; .join là để thực hiện chức năng INNER JOIN. Có vẻ như là trường hợp của bạn, bạn sẽ sử dụng cả hai (tham gia để có được bức ảnh, và bao gồm để có được những người bổ sung). Tôi làm cho điểm này bởi vì .join một mình sẽ không thực hiện tải háo hức (và do đó nó sẽ làm cho các truy vấn sau đó khi các thực thể liên quan được truy cập).

Nếu bạn muốn háo hức tải các hiệp hội lồng nhau, bạn có thể sử dụng cú pháp nêu trong Ruby on Rails hướng dẫn tại http://guides.rubyonrails.org/active_record_querying.html#eager-loading-multiple-associations

Would một cái gì đó dọc theo những dòng làm việc?

Photo.joins(:appearances => :person).includes(:appearances => :person).limit(5) 

Hoặc bạn có cần bắt đầu với người đó không?

Person.joins(:appearances => :photo).includes(:appearances => :photo => :appearaces => :person).limit(5) 

Ngoài ra, như một trận chung kết (nhỏ) lưu ý: bạn phải ": xuất hiện" đánh vần sai trong dòng cuối cùng của bạn mã (nó nói ": appearaces"), mà có thể gây ra vấn đề.

EDIT: Sau một số thử nghiệm nhỏ, dường như làm tổ các hiệp hội bao gồm trong các hình thức

a => b => c => b => a 

không hoạt động. Tuy nhiên, biểu mẫu sau đây có:

a => [b => [c => [b => a]]] 

Mặc dù, tất nhiên, nó không hoàn toàn đẹp.

Ý nghĩa, sử dụng đoạn mã sau:

Person.includes(:appearances => [:photo => [:appearances => :person]]).find(38)  

SQL sau đây được tạo ra:

Person Load (0.3ms) SELECT `persons`.* FROM `persons` WHERE `persons`.`id` = 38 LIMIT 1 
Appearance Load (0.3ms) SELECT `appearances`.* FROM `appearances` WHERE (`appearances`.person_id = 38) 
Photo Load (0.3ms) SELECT `photos`.* FROM `photos` WHERE (`photos`.`id` = 1904) 
Appearance Load (0.3ms) SELECT `appearances`.* FROM `appearances` WHERE (`appearances`.photo_id = 1904) 
Person Load (0.3ms) SELECT `persons`.* FROM `persons` WHERE (`persons`.`id` IN (38,346)) 

Háo hức tải Người bổ sung từ tất cả các hình ảnh bao gồm Person với id # 38

+0

địa ngục vâng, bạn là một ninja! – jdkealy

+0

cuộc gọi tốt trên typo ... đánh máy từ bộ nhớ và không thể đánh vần rõ ràng. – jdkealy

Các vấn đề liên quan