【Rails】ransackで複数モデルから検索したい時
TL;DR
- search_from_forヘルパーは使わない
- viewでは検索ワードのみ取得
- controllerで検索する
環境
Rails 5.2.4.1
Ruby 2.6.5
Ransack 2.3.2
ransackの通常の使い方の延長では無理だった
前提
channelモデルとpostモデルから、検索ワード一致のものをすべて検索したいとします。
1つのモデルから検索する方法はwebにもよく載っていると思います。
# よくあるransackの使い方 # controller def index @search = Channel.ransack(params[:q]) @results = @search.result end
# view # よくあるransackの使い方 = search_form_for @search do |f| .form-group = f.label :title_cont, "Title" = f.search_field :title_cont .actions = f.submit "Search"
ここらは説明不要ですね。
さて、それでは複数モデルから検索するにはどうしましょう?いろいろ検証してみました。
複数モデルからの検索でダメだった方法
検証からちょっと日がたったので若干うろ覚え…
[ダメ1] includesを使う方法
# controller def index @search = Channel.includes(:post).ransack(params[:q]) end
[ダメ2] formにモデルを並列する方法
# controller def index @channel = Channel.ransack(params[:q]) @post = Post.ransack(params[:p]) end # view = search_form_for @channel, @posts do |f| .form-group = f.label :title_and_content_cont, "Title" = f.search_field :title_and_content_cont .actions = f.submit "Search"
解決方法
search_form_forヘルパーを使わない。通常のform_withでコントローラーに検索ワードを送る
# view .search-container = form_with url: search_path, local: true, method: :get do |f| = f.text_field :q = f.submit "検索"
コントローラーで必要なモデル分の検索を行う
class ChannelsController < ApplicationController def search @q = params[:q] @channels = Channel.ransack(title_cont: @q).result @posts = Post.ransack(content_cont: @q).result end ・・・ end
あとはレンダリングすればOKです。
(参考)
Ransackで複数のモデルを一度に検索 - VoidCC