0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

acts-as-taggable-onのtag_listでN+1問題が起きる時の対処

Last updated at Posted at 2021-11-06

概要

簡単にタグ機能を実装できるacts-as-taggable-onというgemがあり、とても便利だが、as_jsonなどのシリアライズするメソッドを使用した際ににN+1問題を引き起こす原因となることがあるのでメモ

詳細

このissueにも書いてあるが

要は、複数のインスタンスに対して、関連するタグを取得するために毎回クエリを発行してしまうのだが、それをうまく回避するための策がない

解決策として、as_json(except: [:tag_list])したり、同様の結果を返すメソッドを定義すればいいと思ったが、インターフェースを変えたくなかった(tag_list: [タグ1, タグ2...]という結果をもうすでに他の場所で利用していた)ので、影響を与えないように、内部の処理だけを変える方法を考えてみた

回避策

いくつか考えたが、自分の環境では、モデルでオーバーライドするのが簡単かつ現実的であった。(あまりしたくないのはもちろんだが)
このtag_listメソッドが実際に定義されているのは、モデルにincludeされている無名モジュールなので、モデルで同名メソッドを定義してオーバーライドできる

some_model.rb
acts_as_taggable_on :tags

def tag_list
  tags.map(&:name)
end

実行してみる

SomeModel.includes(:tags).as_json

# @controller
render json: {
  some_models: SomeModel.includes(:tags)
}

これでN+1問題は発生しないようにできた

気持ち

いっぱいソースコード読んだのでせっかくなのでメモっとこう

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?