Trying to optimize this Active Record Query for better performance in Ruby on Rails

Hello, I'm currently new to active record and exploring two map functions. I'm curious if there's a more efficient way to optimize the following query:

When I run this query, I see hundreds of lines in my terminal and worry about potential memory issues if many users access these conversations simultaneously.

Step 1: Retrieving all relevant conversations.

Step 2: Creating a conversation hash containing sender, recipient, and message information linked to each conversation.

Step 3: Sorting all conversations based on the most recent message, displaying those at the top.

EDIT 1: Rails version 5.0.1

 def index
      i = 1
      @messages = []
      @user = User.find_by(email: params[:email])
      @message = Conversation.where("sender_id = ? OR recipient_id = ?", @user.id, @user.id)
      @message.map { |conversation|
        @messages << conversation if Message.where(conversation_id: conversation.id).count > 0
      }



      render json: @messages.map { |conversation|
        {
          date: conversation.messages.last.created_at,
          sender: User.find(conversation.sender_id),
          recipient: User.find(conversation.recipient_id),
          conversation: {
            id: conversation.id,
            messages: Message.where(conversation_id: conversation.id).sort_by{|e| e[:created_at]}.reverse.map {|message| {
              sender: {
                email: User.find(message.user_id).email,
                first_name: User.find(message.user_id).first_name,
                last_name: User.find(message.user_id).last_nam },
              body: message.body,
              created_at: message.created_at
              }
            }
          }}
      }.sort_by { |hsh| hsh[:date] }.reverse
 end

Answer №1

class Message < ApplicationRecord
  belongs_to :conversation, touch: true
end

class Conversation < ApplicationRecord
  has_many :messages, -> { order(created_at: :desc) }
  belongs_to :sender, foreign_key: :sender_id, class_name: 'User'
  belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
end

class User < ApplicationRecord
  has_many :conversations, -> (user) { unscope(where: :user_id).where('conversations.sender_id = ? OR conversations.recipient_id = ?', user.id, user.id) }
end

class ConversationsController < ApplicationController
  def index
    @user = User.find_by(email: params[:email])

    # "joins(:messages)" allows only retrieving conversations having at least one message, and does not include conversation with 0 message
    # now ordering by `updated_at: :asc` because `Message belongs_to :conversation, touch: true`, in which Conversation's updated_at will be automatically "touched"/updated whenever the associated Messages are updated/created.
    @conversations = @user.conversations.joins(:messages).order(updated_at: :asc).distinct

    json_response = @conversations.as_json(
      only: [:id, :updated_at],
      include: {
        sender: {
          only: [:id, :first_name, :last_name, :email]
        },
        recipient: {
          only: [:id, :first_name, :last_name, :email]
        },
        messages: {
          only: [:body, :created_at]
        }
      }
    )

    render json: json_response
  end

Example Request

Started GET "/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a3c0cccdd5c6d1d0c2d7cacccdd09cc6cec2cacf9ec5ccccc1c2d1e3c6dbc2ced3cfc68dc0ccce">[email protected]</a>"

Example Response

[{
  "id": 2,
  "updated_at": "2018-02-02T11:17:45.376Z",
  "sender": {
    "id": 4,
    "first_name": "Lorem",
    "last_name": "Ipsum",
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2f43405d4a42465f5c5a426f4a574e425f434a014c4042">[email protected]</a>"
  },
  "recipient": {
    "id": 1,
    "first_name": "Foo",
    "last_name": "Bar",
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef8980808d8e9daf8a978e829f838ac18c8082">[email protected]</a>"
  },
  "messages": [{
    "body": "Hello there",
    "created_at": "2018-02-02T11:17:45.367Z"
  }, {
    "body": "Whatcha doin'?",
    "created_at": "2018-02-02T11:17:36.451Z"
  }, {
    "body": "hahaha :)",
    "created_at": "2018-02-02T11:03:29.843Z"
  }]
}, {
  "id": 1,
  "updated_at": "2018-02-02T11:36:14.275Z",
  "sender": {
    "id": 1,
    "first_name": "Foo",
    "last_name": "Bar",
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="24442b48484954474851596347585446410a474b49">[email protected]</a>"
  },
  "recipient": {
    "id": 5,
    "first_name": "Ruby",
    "last_name": "Rails",
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7b242511100f10131415031e271c17181255181416">[email protected]</a>"
  },
  "messages": [{
    "body": "hello Ruby-on-Rails! :)",
    "created_at": "2018-02-02T11:36:14.267Z"
  }]
}]

You can check out how to use .as_json here

You can check out how to use touch: true here

Tested working

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to showcase AJAX data within a complex HTML structure?

I need assistance with displaying the JSON output in my HTML code. My current HTML code is quite complex, so I am unsure how to include this data and repeat the HTML section for every JSON element. Can you provide guidance on how to achieve this? HTML COD ...

The Ajax request is sent with a value of either 0 or null

Struggling to understand why this straightforward ajax call is not working properly. The controller is returning the json file correctly, but for some reason it's logging zeroes for both country and amount values instead of the actual data. What could ...

MVC - transforming a model into a JSON object

In my MVC project, I utilized an Mvc object as my model. My requirement is to stringify my model into a JSON object so that I can use it in JavaScript as needed. Currently, I am implementing something along the lines of: <script type="text/javascript ...

Utilize the Action method selector for distinguishing between Ajax and non-ajax requests, rather than depending on if(Request.isAjaxRequest)?条件

I recently started working through a book titled 'Asp.Net MVC4 in Action'. At one point, the book suggests using an action method selector instead of relying on if statements to check if a request is Ajax. This involves creating a custom class ca ...

Discovering the specific value from a fixture file in Cypress

When I receive a JSON Response, how can I extract the "id" value based on a Username search? For instance, how can I retrieve the response with an "id" value of 1 when searching for the name "Leanne Graham"? It is important to note that the response valu ...

Using JSON parsing to dynamically create classes with preloaded background images

Today, I successfully deployed my browser game using MVC4 to my website for the first time. I am currently navigating through the differences between running the site off of localhost and running it from the actual website. My process involves loading all ...

Undefined Return Value from Node's Exports Function

I have a function that exports data and is supposed to return a JSON array of draft results. However, when I try to access the draft_results variable in the route provided below in app.js, it shows as undefined. app.get('/draft-results', functio ...

Utilizing JSON and Jackson libraries to map JSON data back to Plain Old Java Objects (PO

Currently, I have a JSON string that I want to convert into a POJO: { "fruit": { "weight":"29.01", "texture":null }, "status":"ok" } To achieve this mapping, I am using the Jackson JSON object/JSON mapping framework along with ...

Is there a way to receive live updates for records in real-time using push notifications?

I am in the process of developing a Ruby on Rails ecommerce platform that enables potential customers to place orders while allowing the store owner to receive them instantaneously. Once an order is finalized, it will be saved into the database (currently ...

Receiving JSON using Javascript and vue.js

When attempting to fetch json data in my vue.js application, I use the following code: new Vue({ el: 'body', data:{ role: '', company: '', list:[], ...

Testing the front end by utilizing React in combination with Selenium-Webdriver, while utilizing Rails as the backend

Currently, I am focused on testing the Front-End aspect of my project. Here is the challenge I am encountering: Situation In my setup, I have a well-established Ruby on Rails (V3.2) backend application and a completely new front-end application built wit ...

Sending JSON data from Angular to WCF

Attempting to utilize the post method in Angular to send JSON data to a WCF service. The data is being sent in JSON format from Angular, however, the WCF service is receiving it as a null object. Is it possible to use the get method to send JSON data? Th ...

PHP String Wrapping

I'm currently facing an issue with my code. I have a piece of code that creates an image from an external source of an image and a string. The string is retrieved using json data. The problem arises when I use the string obtained from the json data a ...

Verify if the final (or initial) node containing a child with a specific value

Using XSLT 1.0, I have transformed the given XML into an array of JSON objects: <a id="x"> <active>Yes</active> </a> <a id="y"> <active>No</active> </a> <a id="z"> <active>Yes</act ...

Create JSON containing backslashes by leveraging Jackson

. I am using the Jackson library to create JSON output. Currently, Jackson is generating the JSON in the following format: {"color":"yellow","type":"renault"} However, I need the JSON to be generated with backslas ...

Conducting an AngularJS AJAX call within a Symfony2 environment and utilizing Doctrine to generate a JSON

Currently, I am working on a project involving Symfony2, Doctrine, and AngularJS. While Symfony2 and Doctrine are not causing any issues, I am facing difficulties when using an ajax request with AngularJS. The problem lies in either the data not loading pr ...

Storing kubernetes secrets securely within GitHub Actions

We are currently implementing the use of github actions, with a focus on securely storing sensitive information like kubeconfig within github's secrets. A GitHub secret has been set up under the name KUBECONFIG1 Steps to Replicate The GitHub secret ...

When JSON.stringify is used to convert an object to JSON, it will result in

I'm having difficulty creating a JSON object for transmission over the network. The particular array I'm dealing with looks like this in the Chrome debugger. event: Array[0] $$hashKey: "02Q" bolFromDB: 1 bolIndoor: null ...

Guide to extracting a key from a specific index within JSON using Google Apps Script

Is there a way to extract values key11-key44? Just managed to retrieve values key1-key4: const data = JSON.parse(UrlFetchApp.fetch(url, options); const keys = Object.keys(data.paths); for (let a in keys) {return keys[a]} { "id": &q ...

Transform a Json string into a datatable complete with headers

I am working with a Json string and my goal is to generate a Datatable using the headers provided in that json string. Additionally, I also need to eliminate any escape characters present in the string. Json String [\r\n {\r\n &bs ...