ransack は簡単に検索フォームを作成するためのgemです。
今回は、 ransack の基本的な使い方と、便利なメソッドを紹介したいと思います。
また、ransackには「シンプルモード」と「アドバンスモード」2つの書き方がありますが、ここでは、シンプルモードについて記載します。
RailsのViewでのselectboxの使い方をまとめます。
開発環境
以下のgemを追加します
gem 'ransack'
まず、ベースとなる部分を作成します
Model側
create_table :companies do |t| t.string :name t.string :mail t.string :tel t.datetime :established_date_at t.timestamps end
Controller側
class CompaniesController < ApplicationController def index @q = Company.ransack(params[:q]) @companies = @q.result end end
View側
= search_form_for(@q, url:companies_path) do |f| = f.label :id = f.text_field :id_eq br = f.label :name = f.text_field :name_start br = f.label :established_date = f.text_field :established_date_at_gteq = f.label "~" = f.text_field :established_date_at_lteq br = f.submit br table thead tr th id th name th mail th tel th established_date_at tbody - @companies.each do |company| tr td= company.id td= company.name td= company.mail td= company.tel td= company.established_date_at
これだけの設定で、検索処理が完成しました。
ポイントは、search_form_for内の記載で、検索するカラム名_述語の構成でViewに記載すると述語に応じた検索を行ってくれます。
※ search_form_for はransackが提供するヘルパーです。
上記では、4つの検索項目が定義されていて、それぞれ下記の検索を行います。
項目 | 説明 |
---|---|
id_eq | 完全一致 |
name_start | 前方一致 |
established_date_at_gteq | 範囲検索(以上) |
established_date_at_lteq | 範囲検索(以下) |
定義可能な述語のリストは、公式に記載があるので興味のある方は確認してみてください。
ransackを使用するうえで、便利な ransackable_scopes というメソッドがあるので紹介します。
ransackable_scopesは、スコープで検索するためのメソッドです。
具体的な記載の方法は以下のようになります。
View側
= f.label :name
= f.text_field :custom_scope
Model側
class Company < ApplicationRecord # custom scope scope :custom_scope, lambda { | name | where("companies.name LIKE ? AND companies.established_date_at < ? ", "#{name}%", Time.now) } private # for ransack scope def self.ransackable_scopes(auth_object=nil) %i(custom_scope) end end
self.ransackable_scopes(auth_object=nil)でスコープを指定することができ、指定したスコープをview側で使用することができるようになります。
ここでは、viewで入力された、名前の前方一致と建設日が現在日時より前のデータを取得するようにしています。
発行されるクエリ(ログより)
SELECT `companies`.* FROM `companies` WHERE (companies.name LIKE 'tes%' AND companies.established_date_at < '2019-03-04 14:58:20.594898' )
ransackable_scopesは、0、1、”0”、”1”を暗黙的にTrue、Falseに置き換えてしまいます。
そのため、view側で、上記の数字を入力し検索すると予期せぬ結果になります。(1だとエラーになる)
これを回避するには、config/initializers/ransack.rbを作成し、下記を追記します。
Ransack.configure do |c| c.sanitize_custom_scope_booleans = false end
これで、 ransackable_scopesの暗黙的な置き換え処理の制御できます。