user419017
user419017

Reputation:

Rails 3 how to reduce queries

c = Conversation.joins(:messages).random
>> Conversation Load (8.1ms)  SELECT `conversations`.* FROM `conversations` INNER JOIN `messages` ON `messages`.`conversation_id` = `conversations`.`id` ORDER BY created_at DESC, RAND() LIMIT 1

Count:

c.messages.count
>> (5.7ms)  SELECT COUNT(*) FROM `messages` WHERE `messages`.`conversation_id` = 74

Length:

c.messages.length
>> Message Load (1.2ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`conversation_id` = 82

How to not perform additional queries above? I thought I have already joined messages for the random conversation using INNER JOIN, and yet a new query is performed to count those results?

The second issue is attempting to get all joined messages with a specific user_id:

u = User with id 27 # has messages in 'c' results above
c.messages.where('user_id = ?', u.id).all
>> Message Load (5.3ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`conversation_id` = 82 AND (user_id = 27)

I used select to do this without additional queries:

c.messages.select { |msg| msg.user_id == u.id }
>> returns messages without query logged

I'd still appreciate how I might reduce or optimize these queries.

Upvotes: 1

Views: 651

Answers (1)

MurifoX
MurifoX

Reputation: 15109

Try using includes instead of joins to avoid the n+1 problem.
Railscast #181 By Ryan Bates, http://railscasts.com/episodes/181-include-vs-joins?view=asciicast, explains the difference in an easy way.

Upvotes: 1

Related Questions