mbleigh / acts-as-taggable-on

A tagging plugin for Rails applications that allows for custom tagging along dynamic contexts.
http://mbleigh.lighthouseapp.com/projects/10116-acts-as-taggable-on
MIT License
4.97k stars 1.2k forks source link

Tag queries are performed even though I'm not calling / using the tags #1075

Closed silva96 closed 2 years ago

silva96 commented 2 years ago

UPDATE: This is not a bug of the gem. this is caused only in the Console, with User model that includes devise authenticable module. See https://github.com/mbleigh/acts-as-taggable-on/issues/1075#issuecomment-1016706312


Tag queries are performed even though I'm not calling / using the tags, for example:

irb(main):001:0> User.last
  User Load (0.6ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
  ActsAsTaggableOn::Tagging Load (0.5ms)  SELECT "taggings".* FROM "taggings" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2  [["taggable_id", 83632], ["taggable_type", "User"]]
  ActsAsTaggableOn::Tag Load (0.6ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL)

I don't use the tags everywhere I initialize a user, but it still queries the tags.

I would expect the queries be fired whenever I use something related the tags, like:

  user = User.last
  tags = user.tag_list.join(' ,')

Adding a cache (cached_tag_list) reduces one query

  irb(main):001:0> User.last
  User Load (0.9ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
  ActsAsTaggableOn::Tagging Load (0.8ms)  SELECT "taggings".* FROM "taggings" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2  [["taggable_id", 83632], ["taggable_type", "User"]]

What is weird is that I also have a Post model that has the same cache and tag column name

acts_as_taggable_on :tags

and it does not make a query

  irb(main):001:0> Post.last
  Post Load (0.9ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."id" DESC LIMIT $1  [["LIMIT", 1]]
silva96 commented 2 years ago

Found the culprit,

User class is using devise

devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :validatable, :trackable

UPDATE:

This will only happen when inspecting the result of User.last call, as in the irb console.

calling with ;nil disables the result inspection

irb(main):001:0> User.last;nil
  User Load (0.8ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> nil

When including devise authenticable, the inspect method is overriden by this:

def inspect
  inspection = serializable_hash.collect do |k,v|
     "#{k}: #{respond_to?(:attribute_for_inspect) ? attribute_for_inspect(k) : v.inspect}"
  end
  "#<#{self.class} #{inspection.join(", ")}>"
end

which iterates over all and every attribute of the object, hence, calling the tag attributes and firing the queries.

niuage commented 1 year ago

Thanks a lot for that, wasnt easy to find I bet.