Rails 3 объединяет только определенные строки из отношения

Я думал о том, как Gmail запрашивает их разговоры. Я знаю, что они используют разные технологии, но я хочу имитировать их как можно лучше.

В настоящее время я получаю список разговоров, а затем мне нужно получать сообщения для каждого разговора. Я могу использовать обычное соединение:

Conversation.joins(:messages).first

Но это будет присоединяться к каждому сообщению, а мне нужно только последнее сообщение. Как бы я структурировал этот запрос? Еще лучше было бы присоединиться, когда я делаю Conversation.all:

Conversation.joins(:messages).all # but only join last message for each conversation

Кроме того, могу ли я использовать условия для присоединения к последнему сообщению с определенным идентификатором пользователя?

message.user_id = 1
Conversation.joins(:messages).all # only last message where user_id = 1

Я использую squeel, если это помогает продемонстрировать запрос.

Каков наиболее оптимальный способ извлечения разговоров и последнего сообщения для каждого разговора?


person Damien Roche    schedule 12.09.2012    source источник


Ответы (1)


Это обычно достигается с помощью предложения have. Вы можете сделать что-то подобное в Squeel (примечание, непроверено):

user.conversations.includes{messages}.group{id}.having{messages.id == max(messages.id)}

Вы будете группироваться по идентификатору разговора, а затем использовать необходимость отсеять все строки, кроме строки с максимальным идентификатором сообщения в каждой группе.

Примечание: во многих случаях «иметь» не особенно желательно. Вы захотите проверить объяснение запроса, чтобы убедиться, что вы не причините себе чрезмерную боль в будущем. Если это так, вы можете подумать о добавлении столбца кеша в беседу, указывающего на последнее сообщение в беседе, а затем просто установить связь с этим столбцом.

person Ernie    schedule 12.09.2012
comment
Спасибо! Это очень поможет! - person Damien Roche; 13.09.2012