ActiveRecord z joinami

Mam obiekt usera z asocjacją 1:1 którą chciałbym sobie wciągać pojedynczym zapytaniem SQL JOIN. Próbuję User.includes(:stat).find(1) co robi dwa zapytania, próbuję dalej User.joins(:stat).find(1) i mam fajne zapytanie z JOIN ale nie potrafię dobrać się do JOINowanych z tabeli ‘stats’ danych, u.stat.costam robi mi kolejne zapytanie. Wiecie może jak to zrobić?

Zostaw .includes, bo zawsze będzie ci wykonywało dwa zapytania (nawet jeśli będziesz wyciągał nie jednego, a 20 userów) i jest generalnie lepszym nawykiem niż .joins

(JOIN jest często wolniejszy niż dwa konkretne zapytania do pojedynczych tabel, oraz np. sqlite nie wspiera JOINów)

[quote=Tomash]Zostaw .includes, bo zawsze będzie ci wykonywało dwa zapytania (nawet jeśli będziesz wyciągał nie jednego, a 20 userów) i jest generalnie lepszym nawykiem niż .joins

(JOIN jest często wolniejszy niż dwa konkretne zapytania do pojedynczych tabel, oraz np. sqlite nie wspiera JOINów)[/quote]
dzięki za odpowiedź, IMO jeśli masz właściwe indeksy JOIN zawsze będzie szybszy (myślę o MySQL) - odpadnie co najmniej czas na komunikację/parsowanie po stronie bazy danych i wykonanie kodu po stronie aplikacji. Anyway, czy to oznacza, że się nie da?

0_o?

[quote=pink][quote=Tomash]Zostaw .includes, bo zawsze będzie ci wykonywało dwa zapytania (nawet jeśli będziesz wyciągał nie jednego, a 20 userów) i jest generalnie lepszym nawykiem niż .joins

(JOIN jest często wolniejszy niż dwa konkretne zapytania do pojedynczych tabel, oraz np. sqlite nie wspiera JOINów)[/quote]
dzięki za odpowiedź, IMO jeśli masz właściwe indeksy JOIN zawsze będzie szybszy (myślę o MySQL) - odpadnie co najmniej czas na komunikację/parsowanie po stronie bazy danych i wykonanie kodu po stronie aplikacji. Anyway, czy to oznacza, że się nie da?[/quote]
No dobra, to inaczej, czy w takim razie dobrą praktyką jest wyciąganie sobie danych używając bezpośrednich zapytań i instancjonowanie obiektów z wyników? Na moje oko to wygląda na spory race-condition i nie wydaje się być poprawne, chyba że ActiveRecord robi jakąś magię.

To nawet nie jest bliskie prawdy.

Odpowiadając na pytanie zadane w wątku przez pinka:

u = User.joins(:stat).includes(:stat).find(0) # tu może być chyba joins(:stats), nie jestem pewien

u.stat

Powinno wykonać tylko 1 zapytanie, dość złożony join i przy dostępie do asocjacji nie będzie wykonane drugie. Nie mam tego jak teraz sprawdzić przy asocjacji has_one ale przy has_many/belongs_to działa świetnie.

To nawet nie jest bliskie prawdy.[/quote]
Gwoli ścisłości, wspiera podzbiór joinów – konkretnie tylko jeden typ. A Ty zanim się oburzysz może spojrzyj w oficjalną dokumentację?
http://www.sqlite.org/omitted.html

Active Record wspiera 2 sposóby preładowania obiektów.

a) stary, który robił dużego joina i samemu wszystkie kolumny odpowiednio aliasował
b) nowy, który korzysta z kilku zapytań by osiągnać odpowiedni efekt.

Stary tryb jest wciąż używany kiedy zapytanie o powiązane rekordy ma warunek, którego sprawdzenia wymaga czegoś z oryginalnych rekordów. Jesli nie ma takiej konieczności to railsy używaja nowego trybu. Można wymusić zastosowanie któregoś z nich.

Porównajcie sobie query generowane przez:

Post.includes(:comments) Post.preload(:comments) Post.eager_load(:comments)
http://api.rubyonrails.org/classes/ActiveRecord/Relation.html :

ASSOCIATION_METHODS	=	[:includes, :eager_load, :preload]