tag_names plucks multiple times
Skulli opened this issue · comments
Have an existing Rails 7.0.3 app and installed that gem.
When calling a model with tag_names
on an XYZ.last
Console puts out
Gutentag::Tag Pluck (1.2ms) SELECT "gutentag_tags"."name" FROM "gutentag_tags" INNER JOIN "gutentag_taggings" ON "gutentag_tags"."id" = "gutentag_taggings"."tag_id" WHERE "gutentag_taggings"."taggable_id" = $1 AND "gutentag_taggings"."taggable_type" = $2 [["taggable_id", 38], ["taggable_type", "XYZ"]]
Gutentag::Tag Pluck (0.3ms) SELECT "gutentag_tags"."name" FROM "gutentag_tags" INNER JOIN "gutentag_taggings" ON "gutentag_tags"."id" = "gutentag_taggings"."tag_id" WHERE "gutentag_taggings"."taggable_id" = $1 AND "gutentag_taggings"."taggable_type" = $2 [["taggable_id", 38], ["taggable_type", "XYZ"]]
Oddly when i do Gutentag::ActiveRecord.call self
on the User-class (used with devise) and i do an User.last
User.last
User Load (1.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
Gutentag::Tag Pluck (0.3ms) SELECT "gutentag_tags"."name" FROM "gutentag_tags" INNER JOIN "gutentag_taggings" ON "gutentag_tags"."id" = "gutentag_taggings"."tag_id" WHERE "gutentag_taggings"."taggable_id" = $1 AND "gutentag_taggings"."taggable_type" = $2 [["taggable_id", 4], ["taggable_type", "User"]]
Gutentag::Tag Pluck (0.2ms) SELECT "gutentag_tags"."name" FROM "gutentag_tags" INNER JOIN "gutentag_taggings" ON "gutentag_tags"."id" = "gutentag_taggings"."tag_id" WHERE "gutentag_taggings"."taggable_id" = $1 AND "gutentag_taggings"."taggable_type" = $2 [["taggable_id", 4], ["taggable_type", "User"]]
it calls tag_names directly. Seems the tag_names attribute is calculated on initialize. Did somebody had similar issues?
The second issue might be a different issue on my side, have to check wich addition causes that. Maybe paper_trail or something.
@Skulli I actually noticed something sort of related to your issue, but still digging in a bit.
The biggest thing I found is mostly my own user error, which basically stemmed from abusing convenience methods like tag_names
and over complicating things.
tag_names
is really just the same thing as post.tags.pluck(:name)
and my extra database calls were from calling these in places i didn't realize i was calling it from. Especially tags_as_string
(in my own concern), treating it like it was just an array or string, when they are associated, relational models.
For example, a case where it makes a lot more sense to just use the ActiveRecord
class PostsController < ApplicationController
def show
@post = Post.
.includes(:tags)
.friendly
.find(params[:id])
end
end
<%# app/views/posts/show.html.erb %>
<%= render partial: 'posts/tag', collection: @post.tags, cached: true %>`
<%# app/views/posts/_tag.html.erb %>
<%= link_to tag.name, tag_posts_path(tag_name: tag.name), class: 'badge bg-secondary text-decoration-none link-light', data: {turbo_action: 'replace', turbo_frame: "_top" } %>
vs... things i was doing before, with zero consideration of eager loading or n+1 potential. Just in this simple example below i managed to basically break cache, yield a JOIN call to the layout and then again enumerate in the template as if they were just model properties of the instance.
<%= content_for(:page_keywords, post.tags_as_string %>
<% cache post do %>
<% post.tag_names.each do |name| %>
<%= link_to name, tag_posts_path(tag_name: name), class: 'badge bg-secondary text-decoration-none link-light', data: {turbo_action: 'replace', turbo_frame: "_top" } %>
<% end %>
<% end %>
So my first guess would be something really subtle is actually triggering those loads. I can't actually repo with Post.last
, but this is how it felt when i saw hits to the db well after the controller and during/in the middle of partial rendering.
Thanks for reporting this @Skulli - it was indeed the fault of Gutentag, as part of the complexity of playing nicely with ActiveRecord's dirty state logic. If you want to give the latest commit a spin to confirm it works for you, that'd be appreciated - but either way, I'll try to get a new gem release out soon.
Also, with regards to the auto-populating of tag names when an instance is loaded - I wasn't able to reproduce that, so, as you suggest, I think it might be something in your app.
Just released v2.6.2 with this fix :)