Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching Serializers, fails to cache associations

I am trying to implement some caching with Active Model Serializer; this is my serializer.

class ServiceFieldSerializer < ActiveModel::Serializer
  attributes :id, :name, :description, :meta_description, :content, :practitioner_term, :avatar, :slug
  has_many :services
  embed :id, include: true

  cached
  delegate :cache_key, to: :object

  def services
    object.services.published
  end

  def avatar
    object.image_url :avatar if object.image.present?
  end
end

The service serializer

class ServiceSerializer < ActiveModel::Serializer
  attributes :id, :name, :description, :meta_description, :content, :practitioner_term, :avatar, :slug
  has_one :service_field
  embed :id

  cached
  delegate :cache_key, to: :object

  def avatar
    object.image_url :avatar if object.image.present?
  end
end

Output "y ServiceSerializer.new(Service.first)"

object: !ruby/ActiveRecord:Service
  attributes:
    id: 4
    name: ADHD Coaching
    description: Bliv klogere på hvorfor du har det damp i hovede
    service_field_id: 2
    created_at: 2014-02-18 08:08:41.755177000 Z
    updated_at: 2014-04-29 08:30:44.111671000 Z
    content: tihihi
    image:
    published: true
    meta_description:
    slug: adhd-coaching
    practitioner_term:

My problem is, when i have the cached call, my json response looks like this.

service_fields: []->
0: {id:2, name:Coaching, description:Det bliver du glad for, meta_description:, content:,…}
1: {id:1, name:Massage, description:Massage er godt for krop og alt i hele verden., meta_description:null,…}
2: {id:3, name:Terapi, description:Noget med nogle møder, meta_description:null,…}

As you can see the associated services is missing, if i remove the caching from the serializer the services is there.

What am i doing wrong?

Rails version: 4.0.5

AMS version: 0.8.1

like image 490
MartinElvar Avatar asked Jun 11 '14 09:06

MartinElvar


1 Answers

you are not doing anything wrong... in fact I spent more than a week to figure why this is not working and what i found was that AMS caching doesn't work with sideloaded relations...

but if you want to continue figuring out what is wrong... then have a look at this AMS fork we made to solve this specific issue using the informations found in AMS caching issues...

one thing to note... by using this gem we were able to reduce the amount of time spent querying collections... but it nearly have no effect on loading 1 object... only collections... and we were able to reduce some collections time from 75% to 10% I know that reducing only 10% isn't that good... thats why we are moving to JBuilder now (3 days ago)... and to be honest with you I didn't figure out how it's caching works

EDIT

about jbuilder and caching times... using jbuilder with the appropriate partial caching (fragment caching) we were able to get response times of about 40ms when the collection was not cached and about 15ms when it was cached... the response times before caching was about 130ms (cause fragment caching doesn't invalidate the whole object and it's relations... only the changed parts)... so i recommend using jbuilder with a presenter layer ( like Draper gem ) and jbuilder multi cache for better collection caching

like image 142
a14m Avatar answered Sep 29 '22 06:09

a14m