sql >> Databasteknik >  >> RDS >> PostgreSQL

Rails 4:Att använda PostgreSQL-funktionen i ordning orsakar fel i frågan på grund av att inkluderar-tabellen inte sammanfogas

Anta att du behöver få användarnamnet för de fem första inläggen. Du skriver snabbt frågan nedan och njut av helgen.

posts = Post.limit(5)

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

Bra. Men låt oss titta på frågorna

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 för att hämta alla posts och 1 query för att hämta users för varje inlägg resulterar det i totalt 6 queries . Kolla in lösningen nedan som gör samma sak, bara i 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)

Det är en liten skillnad. Lägg till includes(:posts) till din fråga och problemet löst. Snabbt, trevligt och enkelt.

Men lägg inte bara till includes i din fråga utan att förstå den ordentligt. Att använda includes med joins kan resultera i korskopplingar beroende på situationen, och det behöver du inte i de flesta fall.

Om du vill lägga till villkor för dina medföljande modeller måste du uttryckligen hänvisa till dem . Till exempel:

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

Kommer att ge ett fel, men detta kommer att fungera:

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

Observera att includes fungerar med association names medan references behöver the actual table name .




  1. Base64-kodad sträng för enkel sql-injektion

  2. inlägg omdöpt filnamn från uppladdning till databas

  3. Frågeoptimering i PostgreSQL. FÖRKLARA Grunderna – Del 2

  4. Infoga flera tabeller med transaktion i mysql