LoginSignup
13
7

More than 5 years have passed since last update.

ransack で日付で絞り込む(カスタム検索)

Posted at

はじめに

みなさん ransack は使っていますか?
導入も簡単ですし使いやすいので使っている人も多いことと思います。
基本的な使い方はこちらの記事など参照すればわかりやすいかと。
今回は基本的な使い方にプラスして日付検索をしたかったので ransack でカスタム検索したので github を見ればわかるっちゃわかるんですが、備忘録として書いときます。

やりたいこと

特定の日付の範囲に該当するデータを検索したい。
今回はデータの created_at が指定した日付の範囲の中にあるものを検索します。

やること

フォームに指定した日付の間に created_at がある Post モデルのレコードを取得する。

実装

コントローラー内で使う ransack の search メソッドの第2引数にオプションを追加します。

app/controllers/posts_controller.rb
class PostsController < ApplicatoinController

  def index
    search_options = {
      created_after: params[:created_after]
      created_before: params[:created_before]
    }
    @q = Post.search(params[:q], search_options)
    @posts = @q.result
  end
end

ここではオプションで created_aftercreated_before を設定しています。
これらを設定できるようにビューとモデルにコードを書いていく。

ビューではコントローラ内にある paramas[:created_after]params[:created_berore] を受け取れるように下記のように書く。

app/views/posts/index.html.haml
= search_form_for @q, url: posts_path do |f|
  = f.search_field :created_after
  = f.search_field :created_before
  = f.submit '検索'

- @posts.each do |post|
 = post.title

モデルではオプションのキーで使っている created_aftercreated_before を設定する。

app/models/post.rb
class Post < ApplicationRecord
  scope :created_after, -> (time) {
    time = time.to_time
    where('created_at > ?', time)
  }
  scope :created_before, -> (time) {
    time = time.to_time
    where('created_before > ?', time)
  }

  class << self
    def ransackable_scopes(auth_object = nil)
      [:created_after, :created_before]
    end
  end
end

まずはそれぞれのスコープを作り、クラスメソッドで ransackable_scopes を設定してあげるだけでよい。

まとめ

検索する件数が多くなったり、リクエストの数が増えると ransack だと微妙な面もありますが、
これだけ簡単にカスタム検索できるのは便利なので、社員しか使わないなどであればもってこいかと。

13
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
7