acts-as-taggable-onのtagをRansackの検索対象に含める

違うアプローチを試して少しはまってしまいましたが、 とても簡単に association も考慮して検索することができました。 Ransack 賢いなぁ。

以下は、title と description と tag の like検索になります。

query = { title_or_description_or_tags_name_cont: "ケーキ"}
q = Article.published.ransack(query)
q.result(distinct: true)
SELECT DISTINCT "articles".* FROM "articles"
LEFT OUTER JOIN "taggings"
ON "taggings"."taggable_id" = "articles"."id"
  AND "taggings"."context" = ? AND "taggings"."taggable_type" = ?
LEFT OUTER JOIN "tags"
ON "tags"."id" = "taggings"."tag_id"
WHERE "articles"."status" = ?
AND (("articles"."title" LIKE '%ケーキ%' OR "articles"."description" LIKE '%ケーキ%')
OR "tags"."name" LIKE '%ケーキ%') ORDER BY "articles"."created_at" DESC

 
tagsテーブルは、model で acts_as_taggable した際に has_many through: で関連づけられています。

has_many :base_tags, through: :taggings, source: :tag, class_name: '::ActsAsTaggableOn::Tag'

 
注意事項としては、LEFT OUTTER JOIN での検索になるので distinct しておかないと結果に重複が出る場合があります。