LoginSignup
5
5

More than 5 years have passed since last update.

searchkickで多対多のデータを同期的にインデックスさせる

Posted at

ElasticseachをRubyから扱えるようになるsearchkickというgemがある。

このgemには、例えばUserというモデルにデータが追加されるとそれと同時にElasticsearch側にそのインデックスを作ってくれる便利機能がある。

また、Userを親に持つAddressという子モデルがある場合も以下のように書くとUserに紐づくAddressが新規に追加されたとき同時にインデックスを作成してくれる。

class Address < ActiveRecord::Base
  belongs_to :user

  after_commit :reindex_user

  def reindex_user
    user.reindex
  end
end

1対1や多対1のような関連の時にはこのやり方でいいのだけど、多対多のときは少し工夫が必要になる。

例えば、
(親)Article
(中間)ArticleTagging
(親)Tag
のような多対多の構成の関連があったとき、Articleに紐づくTagが追加されたときにそのTagをインデックスしたいとする。

公式のやり方に則ると下記のようになるけれども、

class Tag < ActiveRecord::Base
  has_many :article_taggings
  has_many :articles, through: :article_taggings

  after_commit :reindex_article

  def reindex_article
    article.reindex
  end
end

これだとうまくいかない。

多対多でもうまく同期的にインデックスさせるためには、下記のように中間モデルに記述する。

class ArticleTagging < ActiveRecord::Base
  belongs_to :tag
  belongs_to :article
  after_commit :reindex # after_saveだとFactoryGirlを使っているときにコケる

  def reindex
    article.reload.reindex
  end
end

これでうまくいく。

【参考】

5
5
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
5
5