From edc27a155b24d12b00d77bbeb761df6e52032354 Mon Sep 17 00:00:00 2001 From: Tanmay Sharma Date: Tue, 22 Jul 2025 11:51:04 +0400 Subject: [PATCH] optimize contacts API query performance --- .../api/v1/accounts/contacts_controller.rb | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/app/controllers/api/v1/accounts/contacts_controller.rb b/app/controllers/api/v1/accounts/contacts_controller.rb index 4fbe50902..e9ea14034 100644 --- a/app/controllers/api/v1/accounts/contacts_controller.rb +++ b/app/controllers/api/v1/accounts/contacts_controller.rb @@ -17,8 +17,8 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController before_action :set_include_contact_inboxes, only: [:index, :active, :search, :filter, :show, :update] def index - @contacts_count = resolved_contacts.count @contacts = fetch_contacts(resolved_contacts) + @contacts_count = @contacts.total_count end def search @@ -29,8 +29,8 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController OR contacts.additional_attributes->>\'company_name\' ILIKE :search', search: "%#{params[:q].strip}%" ) - @contacts_count = contacts.count @contacts = fetch_contacts(contacts) + @contacts_count = @contacts.total_count end def import @@ -55,8 +55,8 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController def active contacts = Current.account.contacts.where(id: ::OnlineStatusTracker .get_available_contact_ids(Current.account.id)) - @contacts_count = contacts.count @contacts = fetch_contacts(contacts) + @contacts_count = @contacts.total_count end def show; end @@ -66,6 +66,7 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController contacts = result[:contacts] @contacts_count = result[:count] @contacts = fetch_contacts(contacts) + rescue CustomExceptions::CustomFilter::InvalidAttribute, CustomExceptions::CustomFilter::InvalidOperator, CustomExceptions::CustomFilter::InvalidQueryOperator, @@ -133,13 +134,14 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController end def fetch_contacts(contacts) - contacts_with_avatar = filtrate(contacts) - .includes([{ avatar_attachment: [:blob] }]) - .page(@current_page).per(RESULTS_PER_PAGE) + # Build includes hash to avoid separate query when contact_inboxes are needed + includes_hash = { avatar_attachment: [:blob] } + includes_hash[:contact_inboxes] = { inbox: :channel } if @include_contact_inboxes - return contacts_with_avatar.includes([{ contact_inboxes: [:inbox] }]) if @include_contact_inboxes - - contacts_with_avatar + filtrate(contacts) + .includes(includes_hash) + .page(@current_page) + .per(RESULTS_PER_PAGE) end def build_contact_inbox @@ -176,11 +178,7 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController end def set_include_contact_inboxes - @include_contact_inboxes = if params[:include_contact_inboxes].present? - params[:include_contact_inboxes] == 'true' - else - true - end + @include_contact_inboxes = params[:include_contact_inboxes] == 'true' end def fetch_contact