Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 662143
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T23:20:43+00:00 2026-05-13T23:20:43+00:00

I have two models: class User end class Message belongs_to :sender, :class_name=> ‘User’ belongs_to

  • 0

I have two models:

class User
end

class Message
 belongs_to :sender, :class_name=> 'User'
 belongs_to :recipient, :class_name=> 'User'
end

I want to fetch all the buddies of a given user ordered by most recent date of message what appears in conversation between given user and his buddy and, if it possible in same query, to fetch the number of message in their conversation.

Now, I’m stuck at this:

Messages.all(:joins => :sender,
   :conditions => ['sender_id = ? OR recipient_id = ?', some_user.id, some_user.id],
   :select => 'users.*, sender_id, recipient_id, MAX(messages.created_at) as last_created, COUNT(messages.id) as messages_count', 
   :group => 'messages.sender_id, messages.recipient_id',
   :order => 'last_created DESC'

That query produce this output:

a)

users.* | sender_id | recipient_id | MAX(last_created) | messages_count
user1   | 1         | 2            | bla               | bla
user1   | 1         | 3            | bla               | bla
user1   | 1         | 4            | bla               | bla

Because models joined by messages.sender_id = user.id I have only user1 records fetched but I need user2, user3 and user4 records in that special situation A when user1 has only send messages to his buddies.

b)

users.* | sender_id | recipient_id | MAX(last_created) | messages_count
user2   | 2         | 1            | bla               | bla
user3   | 3         | 1            | bla               | bla
user4   | 4         | 1            | bla               | bla

In situation B, otherwise, i have what i want to have – all three buddies ordered by most recent date of message what appears in conversation between given user and his buddy.

c)

users.* | sender_id | recipient_id | MAX(last_created) | messages_count
user1   | 1         | 2            | bla               | bla
user3   | 3         | 1            | bla               | bla
user4   | 4         | 1            | bla               | bla

Situation C. user2 as buddy of user1 is missing cause :joins => :sender. Otherwise, if :joins => :recipient would be missing user3 and user4. Thats the cracker. It’s no matter how we join models. How to solve this situation in one query?

  • 1 1 Answer
  • 1 View
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T23:20:44+00:00Added an answer on May 13, 2026 at 11:20 pm

    You need the select_extra_columns gem to return join/aggregate columns. Assuming you have installed the gem, modify your User model as shown below.

    class User
      select_extra_columns
    
    
      def friends_with_conversation
        User.all(
         :select => "users.*, b.last_message_at, b.message_count",
         :joins  => "
                RIGHT JOIN
                 ( SELECT   IF(a.sender_id=#{self.id}, a.recipient_id, 
                                 a.sender_id) AS friend_id, 
                            MAX(a.created_at) AS last_message_at, 
                            COUNT(a.id)       AS message_count
                   FROM     messages AS a
                   WHERE    a.sender_id = #{self.id} OR 
                            a.recipient_id = #{self.id}
                   GROUP BY IF(a.sender_id=#{self.id}, a.recipient_id, 
                                 a.sender_id)
                 ) AS b ON users.id = b.friend_id
               ", 
          :order  => "b.last_message_at DESC",      
          :extra_columns => {:last_message_at=>:datetime, :message_count => :integer}
        )
      end  
    end
    

    Now you can make following calls to get the friend details.

    user.friends_with_conversation.each do |friend|
      p friend.name
      p friend.last_message_at
      p friend.message_count
    end
    

    You need the gem to return last_message_at and message_count in the User object returned by the query.

    Edit
    I am not familiar with PostgresSQL. Cursory reading of the documentation suggests, following SQL might work.

    :joins  => "
     RIGHT JOIN
     ( SELECT   CASE WHEN a.sender_id=#{self.id} 
                     THEN a.recipient_id 
                     ELSE a.sender_id 
                END               AS friend_id, 
                MAX(a.created_at) AS last_message_at, 
                COUNT(a.id)       AS message_count
       FROM     messages AS a
       WHERE    a.sender_id = #{self.id} OR 
                a.recipient_id = #{self.id}
       GROUP BY CASE WHEN a.sender_id=#{self.id} 
                     THEN a.recipient_id 
                     ELSE a.sender_id 
                END
     ) AS b ON users.id = b.friend_id
    "
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Let's say I have two models, Classes and People. A Class might have one
I have two models indexed for searching (User and Item). I'm trying to do
Suppose you have two models, User and City, joined by a third model CityPermission:
I have two models, Article and Post that both inherit from a base model
I have two models. We'll call them object A and object B. Their design
I have two models, Room and Image . Image is a generic model that
I have two models: Person and Relation. The second one stores information about relations
Say that I have two models- Users and Accounts. Each account can have at
I have a situation where I have two models, companies and permissions, where companies
How can I achieve the following? I have two models (blogs and readers) and

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.