Reputation: 327
class Conversation < ApplicationRecord
has_many :messages, dependent: :destroy
belongs_to :organization
has_one :latest_message, -> {
order(created_at: :desc)
}, class_name: "Message", foreign_key: "conversation_id"
end
class Message < ApplicationRecord
belongs_to :conversation
end
How do I order conversation list with the latest_message created_at time.
I tried
conversations.order("latest_message.created_at desc").to_a
but I'm getting the error
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "latest_message"
12:33:07 web.1 | LINE 1: ...E "conversations"."organization_id" = $1 ORDER BY latest_mes...
12:33:07 web.1 | ^
12:33:07 web.1 |
12:33:07 web.1 | from /home/rafi/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/activerecord-6.0.2.2/lib/active_record/connection_adapters/postgresql_adapter.rb:672:in `exec_params'
12:33:07 web.1 | Caused by PG::UndefinedTable: ERROR: missing FROM-clause entry for table "latest_message"
12:33:07 web.1 | LINE 1: ...E "conversations"."organization_id" = $1 ORDER BY latest_mes...
12:33:07 web.1 | ^
possibly because the latest message is not a present in DB; but only in the model.
Upvotes: 0
Views: 55
Reputation: 101811
In ActiveRecord the arguments to .where
, .group
and .order
need to be the actual table names and not associations as they generate SQL.
You don't really need that association at all though:
Conversation.joins(:messages)
.group(:id)
.order("MAX(messages.created_at) DESC")
You may need to use .group('conversations.id')
on some drivers like TinyTDS that will produce an ambiguous GROUP BY id
query instead of GROUP BY "conversations"."id"
. If you want to include conversations that don't have any messages use left_joins
:
Conversation.left_joins(:messages)
.group(:id)
.order("MAX(messages.created_at) DESC")
Upvotes: 1