sql >> Database >  >> RDS >> PostgreSQL

Rails 4:Het gebruik van de PostgreSQL-functie op volgorde veroorzaakt een fout in de query omdat de include-tabel niet wordt samengevoegd

Stel dat u de gebruikersnaam van de eerste vijf berichten moet krijgen. Je schrijft snel onderstaande vraag en gaat genieten van je weekend.

posts = Post.limit(5)

posts.each do |post|
  puts post.user.name
end

Mooi zo. Maar laten we eens kijken naar de vragen

Post Load (0.5ms)  SELECT  `posts`.* FROM `posts` LIMIT 5
User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE  `users`.`id` = 1 LIMIT 1
User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE  `users`.`id` = 1 LIMIT 1
User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE  `users`.`id` = 2 LIMIT 1
User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE  `users`.`id` = 2 LIMIT 1
User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE  `users`.`id` = 1 LIMIT 1

1 query om alle posts op te halen en 1 query om users op te halen voor elk bericht resulteert in een totaal van 6 queries . Bekijk de onderstaande oplossing die hetzelfde doet, alleen in 2 queries :

posts = Post.includes(:user).limit(5)

posts.each do |post|
  puts post.user.name
end

#####

Post Load (0.3ms)  SELECT  `posts`.* FROM `posts` LIMIT 5
User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2)

Er is één klein verschil. Voeg includes(:posts) toe op uw vraag, en probleem opgelost. Snel, leuk en gemakkelijk.

Maar voeg niet alleen includes toe in uw vraag zonder het goed te begrijpen. Het gebruik van includes met joins kan resulteren in cross-joins, afhankelijk van de situatie, en dat heb je in de meeste gevallen niet nodig.

Als u voorwaarden wilt toevoegen aan uw opgenomen modellen, moet u hier expliciet naar verwijzen . Bijvoorbeeld:

User.includes(:posts).where('posts.name = ?', 'example')

Zal een foutmelding geven, maar dit zal werken:

User.includes(:posts).where('posts.name = ?', 'example').references(:posts)

Merk op dat includes werkt met association names terwijl references heeft the actual table name nodig .




  1. MySQL - Vind rijen die overeenkomen met alle rijen van samengevoegde tabel

  2. OSX 10.9 Mavericks en Eclipse Kepler (4.3.2) of M6 Eclipse Luna (4.4)

  3. sqlalchemy dwingt alle verbindingen om mysql . te sluiten

  4. Hoe parallelle plannen opstarten - Deel 3