rails query join,order by,group by issue

时间:2013-11-08 17:36:31

标签: ruby-on-rails join group-by

项目中有三个模型

  • 会话
  • conversation_message
  • 消息

Conversation.rb

class Conversation < ActiveRecord::Base
    #subject
    has_many :conversation_messages, :dependent => :destroy
    has_many :messages, :through => :conversation_messages, :dependent => :destroy, :order => "created_at DESC"
end

ConversationMessage.rb

class ConversationMessage < ActiveRecord::Base
  #conversation_id, message_id
  belongs_to :conversation
  belongs_to :message, :dependent => :destroy
end

Message.rb

#sender_id, receiver_id, message

has_one :conversation_message, :dependent => :destroy
has_one :real_conversation, :through => :conversation_message, :source => "conversation"

所以我想检索current_user的所有会话,并希望按照收到或发送的最后一条消息的顺序显示它们。 还希望显示其所有消息的单个对话,并且必须通过其中包含的消息对对话进行排序。 使用rails 3.0

我尝试了以下查询,但下面给出了一个错误 查询

@user_conversations = Conversation
.joins(:messages)
.where(["messages.receiver_id = ?  or messages.sender_id = ?", current_user.id, current_user.id ])
.group("conversations.id").order("messages.created_at DESC")

错误

PG::GroupingError: ERROR:  column "messages.created_at" must appear in the GROUP BY clause or be used in an aggregate function

2 个答案:

答案 0 :(得分:21)

您需要在messages.created_at子句中加入group

@user_conversations = Conversation
.joins(:messages)
.where(["messages.receiver_id = ?  or messages.sender_id = ?", current_user.id, current_user.id ])
.group("conversations.id, messages.created_at")
.order("messages.created_at DESC")

请参阅:column "users.id" must appear in the GROUP BY clause or be used in an aggregate function

答案 1 :(得分:6)

您可以使用

避免显示多个会话

.order("max(messages.created_at) DESC")

并从messages.created_at部分删除group

@user_conversations = Conversation
.joins(:messages)
.where(["messages.receiver_id = ?  or messages.sender_id = ?", current_user.id, current_user.id ])
.group("conversations.id")
.order("max(messages.created_at) DESC")

它为您提供“按最新评论排序的唯一对话”。

这不是纯粹按messages.created_at排序,但改变maxminDESCASC会完成你想要的工作,我想。 / p>