Files
openfoodnetwork/app/serializers/api/admin/order_serializer.rb
Pau Perez 20a7f2f24e Eager load payment and subs. order associations
This removes the N+1 queries caused by
`Api::Admin::OrderSerialier#ready_to_capture` when used from
`Api::OrdersController#index`. While it's fine for the single-order
controller actions, it's not for this one that deals with a collection
of orders.

Fortunately, `SearchOrders` is used only in this controller action so we
can put the `includes` calls there, otherwise, we would need to refactor
it a bit to pass in a context-specific AR relation.
2021-02-23 10:26:12 -08:00

80 lines
2.2 KiB
Ruby

# frozen_string_literal: true
module Api
module Admin
class OrderSerializer < ActiveModel::Serializer
attributes :id, :number, :user_id, :full_name, :email, :phone, :completed_at, :display_total,
:edit_path, :state, :payment_state, :shipment_state,
:payments_path, :ready_to_ship, :ready_to_capture, :created_at,
:distributor_name, :special_instructions, :display_outstanding_balance,
:item_total, :adjustment_total, :payment_total, :total
has_one :distributor, serializer: Api::Admin::IdSerializer
has_one :order_cycle, serializer: Api::Admin::IdSerializer
def full_name
object.billing_address.nil? ? "" : ( object.billing_address.full_name || "" )
end
def distributor_name
object.distributor.andand.name
end
def display_outstanding_balance
return "" if object.outstanding_balance.zero?
object.display_outstanding_balance.to_s
end
def edit_path
return '' unless object.id
spree_routes_helper.edit_admin_order_path(object)
end
def payments_path
return '' unless object.payment_state
spree_routes_helper.admin_order_payments_path(object)
end
# This methods requires to eager load the payment association (with its required WHERE
# constraints) so as not to cause and N+1.
def ready_to_capture
pending_payments = object.pending_payments.reject(&:authorization_action_required?)
object.payment_required? && pending_payments.any?
end
def ready_to_ship
object.ready_to_ship?
end
def display_total
object.display_total.to_html
end
def email
object.email || ""
end
def phone
object.billing_address.nil? ? "a" : ( object.billing_address.phone || "" )
end
def created_at
object.created_at.blank? ? "" : I18n.l(object.created_at, format: '%B %d, %Y')
end
def completed_at
object.completed_at.blank? ? "" : I18n.l(object.completed_at, format: '%B %d, %Y')
end
private
def spree_routes_helper
Spree::Core::Engine.routes.url_helpers
end
end
end
end