acts-as-taggable-on icon indicating copy to clipboard operation
acts-as-taggable-on copied to clipboard

N+1 SQL query problem with serialization due to tag_list

Open lukes opened this issue 3 years ago • 3 comments

Hi!

The use of attribute for tag_list appears to be responsible for an N+1 SQL query problem when taggable records are serialized.

Example:

MyTaggableModel.all.as_json 
# => Observe the N+1 problem calls to `ActsAsTaggableOn::Tagging` and `ActsAsTaggableOn::Tag`

This is due to the attribute's inclusion in #serializable_hash:

MyTaggableModel.new.serializable_hash # => `Hash` includes "tag_list" key

Our workaround, because we do not need tag_list to be serialized is to always exclude: it:

MyTaggableModel.all.as_json(exclude: :tag_list)

But this is a gotcha if we ever serialize a collection of records that are taggable, and forget to do this.

lukes avatar Apr 05 '21 23:04 lukes

I ran into this same issue when fragment caching taggable records. I overrode the serializable_hash method on models using acts-as-taggable as a workaround.

private

def serializable_hash
  self.attributes.reject{ |k, v| k == 'tag_list' }
end

Wondering if there is a better solution?

ggladden avatar Aug 04 '21 13:08 ggladden

I'm having the same issue, it isn't a nice default i guess, it should be opt-in

rieg-ec avatar Nov 15 '22 17:11 rieg-ec

I personally use serizlizer to do the handling with the following code. I would be happy if this information is useful to anyone!

class Model < ApplicationRecord
   acts_as_taggable
end

class ModelSerializer < ApplicationSerializer
  attributes :tag_list,

  has_many :tags

  # delegate :tag_list, to: :object

  def tag_list
    object.tags.pluck(:name)
  end
end

neco3s avatar Jun 05 '23 14:06 neco3s