10

在项目中有三个模型

  • 对话
  • 对话消息
  • 信息

对话.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

会话消息.rb

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

消息.rb

#sender_id, receiver_id, message

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

所以我想检索current_user所有对话,并希望按照收到或发送的最后一条消息的顺序显示它们。还希望为其所有消息显示单个对话,并且对话必须按其中包含的消息排序。使用导轨 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
4

2 回答 2

28

您需要messages.created_atgroup子句中包含:

@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")

请参阅:列“users.id”必须出现在 GROUP BY 子句中或在聚合函数中使用

于 2013-11-08T17:41:08.730 回答
6

您可以通过使用避免显示多个对话

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

messages.created_atgroup部分中删除。

@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而是通过改变maxand minand DESCandASC来完成你想要的工作。

补充:我写这个答案已经很多年了,我发现如果没有消息,这不会返回记录。
为了处理你需要在查询中添加NULLS LASTNULLS FIRST(对于postgreql,我不知道对于mysql)。
前任。.order("max(messages.created_at) DESC NULLS LAST")

于 2015-08-04T09:36:14.270 回答