PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Rails 4:Die Verwendung der PostgreSQL-Funktion in der Reihenfolge verursacht einen Fehler in der Abfrage, da die Includes-Tabelle nicht verknüpft wird

Angenommen, Sie müssen den Benutzernamen der ersten fünf Beiträge abrufen. Du schreibst schnell die folgende Abfrage und genießt dein Wochenende.

posts = Post.limit(5)

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

Gut. Aber schauen wir uns die Abfragen an

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 um alle posts abzurufen und 1 query um users abzurufen für jeden Beitrag ergibt sich insgesamt 6 queries . Schauen Sie sich die folgende Lösung an, die dasselbe tut, nur 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)

Es gibt einen kleinen Unterschied. Fügen Sie includes(:posts) hinzu zu deiner Frage und Problem gelöst. Schnell, nett und einfach.

Aber fügen Sie nicht einfach includes hinzu in Ihrer Anfrage, ohne sie richtig zu verstehen. Die Verwendung von includes mit joins kann je nach Situation zu Cross-Joins führen, was in den meisten Fällen nicht erforderlich ist.

Wenn Sie Ihren eingeschlossenen Modellen Bedingungen hinzufügen möchten, müssen Sie explizit darauf verweisen . Zum Beispiel:

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

Wird einen Fehler auslösen, aber das wird funktionieren:

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

Beachten Sie, dass includes funktioniert mit association names während references benötigt the actual table name .