カテゴリ: Rails 更新日: 2025/12/04

Railsの検索とフィルタの設計!初心者でもわかるParamsとクエリオブジェクトの使い方

検索・フィルタの設計:クエリオブジェクト/Paramsオブジェクト導入法
検索・フィルタの設計:クエリオブジェクト/Paramsオブジェクト導入法

先生と生徒の会話形式で理解しよう

生徒

「Railsで一覧表示の検索や絞り込みをしたいんですが、どこに書けばいいのかわかりません…」

先生

「それなら、コントローラをスッキリ保ちながら検索を実装できる方法がありますよ。」

生徒

「パラメータをどう処理するのかもよく分からなくて…」

先生

「それでは、Paramsオブジェクトとクエリオブジェクトを使って、検索とフィルタ処理を分かりやすく設計する方法を学びましょう!」

1. Railsで検索・フィルタをする場面とは?

1. Railsで検索・フィルタをする場面とは?
1. Railsで検索・フィルタをする場面とは?

Webアプリケーションでは、データの一覧画面で検索フィルタ(絞り込み)が必要になる場面がよくあります。たとえば、ブログ記事をタイトルで検索したり、カテゴリーで絞り込んだりするケースです。

Railsでは、こういった機能をコントローラに直接書くこともできますが、それではコードが長くなり、メンテナンスがしづらくなってしまいます。そこで、検索専用の処理を切り出す「クエリオブジェクト」や、パラメータを整理して使いやすくする「Paramsオブジェクト」が登場します。

2. パラメータとは?Paramsの基本

2. パラメータとは?Paramsの基本
2. パラメータとは?Paramsの基本

パラメータとは、ユーザーが検索フォームなどから送信する「条件」のことです。Railsでは、この情報はparamsというハッシュの形でコントローラに渡されます。

たとえば、タイトルを検索するフォームで「Ruby」と入力した場合、以下のようなリクエストになります。


<form action="/posts" method="get">
  <input type="text" name="title" value="Ruby">
  <button type="submit">検索</button>
</form>

このフォームを送信すると、URLには?title=Rubyのようにパラメータが付きます。Railsではこれを次のように受け取ります。


params[:title]  #=> "Ruby"

3. フィルタ処理をコントローラに書くとどうなる?

3. フィルタ処理をコントローラに書くとどうなる?
3. フィルタ処理をコントローラに書くとどうなる?

検索や絞り込みの処理をすべてコントローラに書くと、次のようにゴチャゴチャしてしまいます。


def index
  posts = Post.all
  posts = posts.where("title LIKE ?", "%#{params[:title]}%") if params[:title].present?
  posts = posts.where(category: params[:category]) if params[:category].present?
  render :index, locals: { posts: posts }
end

このように、条件が増えるとコントローラの中身がどんどん複雑になっていきます。これでは、コードの再利用やテストがしづらくなります。

4. クエリオブジェクトで検索処理を整理しよう

4. クエリオブジェクトで検索処理を整理しよう
4. クエリオブジェクトで検索処理を整理しよう

そこで登場するのがクエリオブジェクトです。検索専用のクラスを作ることで、ロジックをスッキリまとめることができます。

次のようなPostSearchクラスを作成します。


class PostSearch
  def initialize(params)
    @params = params
  end

  def results
    scope = Post.all
    scope = scope.where("title LIKE ?", "%#{@params[:title]}%") if @params[:title].present?
    scope = scope.where(category: @params[:category]) if @params[:category].present?
    scope
  end
end

コントローラ側は次のようにシンプルになります。


def index
  search = PostSearch.new(params)
  render :index, locals: { posts: search.results }
end

これにより、ロジックと表示の分離ができ、保守性の高いコードになります。

5. Paramsオブジェクトでパラメータの取り扱いを安全に

5. Paramsオブジェクトでパラメータの取り扱いを安全に
5. Paramsオブジェクトでパラメータの取り扱いを安全に

さらに一歩進めて、Paramsオブジェクトを使うことで、パラメータの安全性や意図の明確化ができます。

次のように、Strong Parametersの仕組みを使って安全なパラメータだけを許可します。


def search_params
  params.permit(:title, :category)
end

これをクエリオブジェクトに渡せば、不正なパラメータが混入するのを防げます。


search = PostSearch.new(search_params)

6. 検索フォームとの連携

6. 検索フォームとの連携
6. 検索フォームとの連携

クエリオブジェクトとParamsオブジェクトを使えば、検索フォームともスムーズに連携できます。

例えば、indexページに以下のようなフォームを用意します。


<form action="/posts" method="get" class="mb-3">
  <input type="text" name="title" placeholder="タイトルで検索" class="form-control mb-2">
  <select name="category" class="form-select mb-2">
    <option value="">すべてのカテゴリ</option>
    <option value="tech">技術</option>
    <option value="life">生活</option>
  </select>
  <button type="submit" class="btn btn-primary">検索</button>
</form>

検索条件を入力して送信すると、コントローラがクエリオブジェクトで結果を取得し、ビューに表示する仕組みです。

7. 使い方の工夫と応用

7. 使い方の工夫と応用
7. 使い方の工夫と応用

このような設計にすると、次のようなメリットがあります。

  • テストしやすくなる(クエリオブジェクトを単体でテスト可能)
  • 条件の追加や変更がしやすい
  • 複数の画面で共通の検索処理を使い回せる

Railsでよくある検索機能フィルタ機能を実装する際は、このように「責務を分ける設計」を意識すると、アプリ全体が読みやすく、拡張しやすくなります。

関連記事:
カテゴリの一覧へ
新着記事
New1
データベース
SQLの処理が遅くなる原因とは?初心者向けにデータベースパフォーマンス最適化を完全解説
New2
Ruby
RubyのネストHash操作を徹底解説!digとtransformメソッドで複雑なデータも楽々
New3
Rails
Railsインデックス設計の極意!爆速サイトを作るためのスキーマ設計ガイド
New4
データベース
SQLのCOMMITとROLLBACKとは?トランザクション操作を初心者向けに完全解説
人気記事
No.1
Java&Spring記事人気No1
Rails
Railsで日本語と時刻の設定をしよう!初心者でも安心のlocale/zone初期設定チートシート
No.2
Java&Spring記事人気No2
Ruby
PATHと環境変数の正しい設定!Windows・Mac・Linux別チェックリスト付き
No.3
Java&Spring記事人気No3
Ruby
Rubyのハッシュを徹底比較!シンボルキーと文字列キーの違いと使い分け
No.4
Java&Spring記事人気No4
Rails
Railsマイグレーションの型選びを完全ガイド!初心者が迷わないカラム設計
No.5
Java&Spring記事人気No5
Ruby
WindowsでRubyをインストールする方法!RubyInstallerとMSYS2を使った完全ガイド
No.6
Java&Spring記事人気No6
Rails
RailsモデルとActive Record基礎|ID戦略を完全理解!AUTO INCREMENT・UUID・ULIDの比較と導入手順
No.7
Java&Spring記事人気No7
データベース
ACID特性とは?データベーストランザクションの信頼性を初心者向けに徹底解説
No.8
Java&Spring記事人気No8
Rails
RailsモデルとActive Record基礎|クエリログの読み方を理解してEXPLAIN・joins・includesの違いを学ぼう