Search code examples
ruby-on-railsactiverecordserializationactive-model-serializers

Slow serialization permormance in rails 4 with activemodel serializers


Removed N+1 queries but it didn't help me. There are only 40 objects and it takes 15 seconds.

I quess there are so many Stock.with_translations(I18n.locale) and Distributor.with_translations(I18n.locale) db calls that serializing works so slowly. How could I refactor that db calls?

 class ShopsSerializer < ActiveModel::Serializer
    include ActionView::Helpers::SanitizeHelper

    attributes :id, :title, :description, :audio_sizes, :stocks_count, :image_sizes, :audio_count, :country
    has_many :images, serializer: ShopImageSerializer
    has_many :products, serializer: ProductSerializer

    def image_sizes
      total = 0.0

      stocks = Stock.with_translations(I18n.locale).includes(:images).where(city_id: object.id)
      stocks.each do |stock|
        sum = stock.images.inject(0){|sum, item| sum + item.image_size if item.image.present?} || 0
        total += sum
      end

      total.round(2)
    end

    def audio_sizes
      size = 0.0
      Stock.with_translations(I18n.locale).where(city_id: object.id).map{|s| size += s.audio.size if s.audio.present?}
      Distributor.with_translations(I18n.locale).where(city_id: object.id).map{|d| size += d.audio.size if d.audio.present?}
      size
    end

    def stocks_count
      Stock.with_translations(I18n.locale).where(city_id: object.id).count + Distributor.with_translations(I18n.locale).where(city_id: object.id).count
    end

    def audio_count
      count = 0
      Stock.with_translations(I18n.locale).where(city_id: object.id).map do |s|
        if s.audio.present?
          count += 1
        end
      end

      Distributor.with_translations(I18n.locale).where(city_id: object.id).map do |d|
        if d.audio.present?
          count += 1
        end
      end
      count
    end
  end

Solution

  • Using rails caching instead of activemodel serializers caching solved my problem. link