記事の概要
前回の記事の続きで検索シリーズ第3弾。今回はアソシエーションしたテーブルから検索できるようにする。
例えばarticlesテーブルがあり、一つのarticleにはタグ付けができるとする。タグはtagsテーブルにあり、中間テーブルを介してarticlesテーブルとtagsテーブルは多対多のアソシエーションであった時、articleをtag名で検索したい。
準備
まず、Articleモデル。
models/article.rb
class Article < ApplicationRecord
has_many :article_tag_relations
has_many :tags, through: :article_tag_relations
end
Tagモデル。tagsテーブルにはタグ名が入るtagnameカラムがあるとする。
models/tag.rb
class Tag < ApplicationRecord
has_many :article_tag_relations
has_many :articles, through: :article_tag_relations
end
ArticleTagRelationモデルで中間テーブルを作る。
models/article_tag_relations.rb
class ArticleTagRelation < ApplicationRecord
belongs_to :article
belongs_to :tag
end
検索機能の実装
ビューファイルで検索フォームを実装。
search.html.erb
<%= form_with(url: tagsearch_articles_path, local: true, method: :get) do |form| %>
<%= form.text_field :tag %>
<%= form.submit "search" %>
<% end %>
コントローラーの記述。検索時に、joinsメソッドで関連するテーブル同士、ここではarticlesテーブルとtagsメソッドを内部結合させるのがポイント。これにより、本来tagsテーブルのカラムであるtagnameで検索した結果としてのarticlesテーブルのレコードを取得できる。
articles_controller.rb
def tagsearch
# 検索フォームから送られてくるパラメータ
@tag = params[:tag]
# joinsメソッドでテーブル同士を結合。検索は一致検索とする。
@articles = Article.joins(:tags).where('tagname LIKE ?',"#{@tag}")
end