2015-05-23 2 views
1

Message моделиActiveRecord Group по 2 колонки

user_id  # owner of the message 
sender_id # user that sent message 
receiver_id # user then recieved message 
content  # content of message 

У меня есть Messages. Я хотел бы сгруппировать их по sender_id и receiver_id, так как это «цепочка бесед».

Когда я группа я получаю результаты, которые выглядят как

[1,3] => 5 # user 1 and 3 have 5 messages 
[1,6] => 2 # user 1 and 6 have 2 messages 
[3,1] => 3 # user 3 and 1 have 3 messages 

Действительно [1,3] и [3,1], являются частью одной и той же «группы». Как я могу это достичь?

ответ

2

Вы можете получить это по сортировке sender_id и recipient_id использованием LEAST() и GREATEST() (по крайней мере, в Postgres и MySQL).

Вот fiddle демонстрирует SQL:

SELECT 
    LEAST(sender_id, receiver_id), 
    GREATEST(sender_id, receiver_id), 
    count(*) 
FROM messages 
GROUP BY 
    LEAST(sender_id, receiver_id), 
    GREATEST(sender_id, receiver_id) 

И в ActiveRecord эквивалент:

Message.group('LEAST(sender_id, receiver_id), GREATEST(sender_id, receiver_id)').count 
+0

Не работает в моем текущем dev env. Я использую mysqlite для dev ... мне не нужно было обновляться до Postgres в dev .... возможно, я должен теперь .... но скорее не буду сейчас, когда я пытаюсь быстро нажимать функции. – slindsey3000

+0

Любой способ сделать это с помощью ActiveRecord? – slindsey3000

+1

'ActiveRecord' является только адаптером для вашей БД, поэтому вам нужно будет разобраться, как SQLite будет это делать. Или, как только вы получите свой текущий набор результатов, объедините их в Ruby [например] (http://rubyfiddle.com/riddles/92a08). –

1

Используя трюк, представленную @ Кристьян, вы можете объединить [1,3] и [1,3] рубина вместо использования SQL функции:

thread_messages_count = Hash.new(0) 
Message.group(:sender_id, :receiver_id).count.each do |k, v| 
    thread_messages_count[k.sort] += v 
end 
Смежные вопросы