Jest to raczej pytanie „dlaczego to działa w ten sposób”, a nie pytanie „nie wiem jak to zrobić” ...
Dlatego ewangelią związaną z :include
pobieraniem powiązanych rekordów, z których wiesz, że będziesz korzystać, jest skorzystanie, ponieważ dostaniesz połączenie i unikniesz mnóstwa dodatkowych zapytań:
Post.all(:include => :comments)
Jednak gdy spojrzysz na dzienniki, nie nastąpi żadne połączenie:
Post Load (3.7ms) SELECT * FROM "posts"
Comment Load (0.2ms) SELECT "comments.*" FROM "comments"
WHERE ("comments".post_id IN (1,2,3,4))
ORDER BY created_at asc)
To jest na skróty, ponieważ ciągnie wszystkie komentarze na raz, ale to nie jest jeszcze dołączyć (czyli to, co wydaje się cała dokumentacja powiedzieć). Jedynym sposobem na uzyskanie sprzężenia jest użycie :joins
zamiast :include
:
Post.all(:joins => :comments)
A dzienniki pokazują:
Post Load (6.0ms) SELECT "posts".* FROM "posts"
INNER JOIN "comments" ON "posts".id = "comments".post_id
Czy coś brakuje? Mam aplikację z pół tuzinem skojarzeń i na jednym ekranie wyświetlam dane ze wszystkich. Wydaje się, że lepiej byłoby mieć jedno zapytanie łączone zamiast 6 osób. Wiem, że pod względem wydajności nie zawsze lepiej jest łączyć zamiast pojedynczych zapytań (w rzeczywistości jeśli spędzasz czas, wygląda na to, że dwa powyższe zapytania są szybsze niż łączenie), ale po wszystkich dokumentach Czytam, jestem zaskoczony, widząc, że :include
nie działa zgodnie z reklamą.
Może Railsy są świadome problemu z wydajnością i nie dołączają, z wyjątkiem niektórych przypadków?
includes
(dla każdego, kto to czyta)