The following is the Message model
class Message < ApplicationRecord
belongs_to :parent_message, class_name: 'Message', optional: true
has_many :child_messages, foreign_key: :parent_message_id, class_name: "Message"
has_many :message_participants
scope :latest_messages_by_participant, -> (user_id) do
select("DISTINCT ON (parent_message_id) messages.*").
joins(:message_participants).
where(message_participants: { user_id: user_id }).
order("parent_message_id, created_at DESC")
end
end
message_participants
has a record for each message and the various people who have sent or received that message. It has a user_id on it.
The problem with the above latest_messages_by_participant
scope is that it is able to get all the child messages BUT it gets only the last parent message. That is because we are calling DISINTICT ON on parent_message_id, and for childless parent messages this value is NULL and so it's just calling distinct on NULL and returns on 1 value (the last childless parent message).
How can I fetch all the latest messages including the latest child messages AND the latest childless parent message in a single query?
I'm using Rails 6 and Postgres 11.
P.S: I should also point out a secondary problem which is that the messages are returned in created_at ASC. The created_at DESC is able to get the latest child message but does not sort the overall collection. I can solve this by calling .reverse, but wondering if there was a way to fix that as well.