rails query join, order by, group by issue
Posted
技术标签:
【中文标题】rails query join, order by, group by issue【英文标题】: 【发布时间】:2013-11-20 19:49:29 【问题描述】:项目中有三个模型
对话 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
消息.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
【问题讨论】:
【参考方案1】:您需要在group
子句中包含messages.created_at
:
@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
【讨论】:
我想显示单个会话的所有相关消息,并且会话列表必须按进入会话的消息排序。【参考方案2】:您可以通过使用来避免显示多个对话
.order("max(messages.created_at) DESC")
并从group
部分中删除messages.created_at
。
@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")
它为您提供“最新 cmets 排序的独特对话”。
这不仅仅是通过messages.created_at
订购,而是通过更改max
和min
和DESC
和ASC
来完成你想要的工作,我猜。
添加:
我写这个答案已经很多年了,我发现如果没有消息,这不会返回记录。
为了处理您需要在查询中添加NULLS LAST
或NULLS FIRST
(对于postgreql,我不知道对于mysql)。
前任。 .order("max(messages.created_at) DESC NULLS LAST")
【讨论】:
哇,非常感谢。包含max()
是这个工作和不工作之间的区别 - 它让我的大脑好几天。以上是关于rails query join, order by, group by issue的主要内容,如果未能解决你的问题,请参考以下文章