9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails with RANSACK

Last updated at Posted at 2019-04-09

Rails with RANSACK

前回の投稿でなんとか、CRUDの基本的なところまでModal Formを使用した構成で実現できました!
今回は、登録・更新されたテーブルに対して、一覧検索機能をつけたいと思いました。

要件

  • 一覧画面に一覧検索機能を付加する
  • 検索要件
    • User.id:完全一致
    • User.name:前方後方部分一致
    • User.created_at:以上・以下範囲検索
    • User.updated_at:以上・以下範囲検索

なぜRANSACK?

Google先生に「Rails 一覧検索」みたいな感じでお伺いを立てましたが、当たり前ですが、ActiveRecordの#where()であったり、を書かなくてはならないようでした。確かにそれでも問題ないのですが、SQLをなるべくなら書きたくないということで、漁ったところRANSACKというGemに出会いました。

いざRANSACK

では導入してみましょう

Gemfile

Gemfile
gem 'ransack'

と記載し、

terminal
$ bundle install

しましょう。

form.html.erb

form.html.erb
<%= search_form_for @q do |f| %>
	<div class="form-group">
		<%= f.label :name_cont, "name", class: "font-weight-bold" %>
		<%= f.search_field :name_cont, class: "form-control" %>
	</div>
	<%= f.submit sanitize('<i class="fa fa-search"></i> Search'), class: "btn btn-dark" %>
<% end %>

注意点として

  • form_forの代わりにsearch_form_forを使用すること
  • [カラム名]_[検索条件]で検索条件を指定します。

検索条件の指定

_eq
User.ransack(name_eq: "test").result
# SELECT users.* FROM users WHERE users.name = 'test';
_not_eq
User.ransack(name_not_eq: "test").result
# SELECT users.* FROM users WHERE users.name != 'test';
_matches
User.ransack(name_matches: "test").result
# SELECT users.* FROM users WHERE users.name LIKE 'test';

User.ransack(name_matches: "test%").result
# SELECT users.* FROM users WHERE users.name LIKE 'test%';
_does_not_match
User.ransack(name_does_not_match: "test").result
# SELECT users.* FROM users WHERE users.name NOT LIKE 'test';
_matches_any
User.ransack(name_matches_any: "test").result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test' );
User.ransack(name_matches_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test' OR users.name LIKE 'hoge' );
_matches_all
User.ransack(name_matches_all: "test").result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test' );
User.ransack(name_matches_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test' AND users.name LIKE 'hoge' );
_does_not_match_any
User.ransack(name_does_not_match_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE 'test' OR users.name NOT LIKE 'hoge' );
_does_not_match_all
User.ransack(name_does_not_match_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE 'test' AND users.name NOT LIKE 'hoge' );
_lt
User.ransack(created_at_lt: "2019-01-01 00:00:00").result
# SELECT users.* FROM users WHERE users.created_at < '2019-01-01 00:00:00';
_lteq
User.ransack(created_at_lteq: "2019-01-01 00:00:00").result
# SELECT users.* FROM users WHERE users.created_at <= '2019-01-01 00:00:00';
_gt
User.ransack(created_at_gt: "2019-01-01 00:00:00").result
# SELECT users.* FROM users WHERE users.created_at > '2019-01-01 00:00:00';
_gteq
User.ransack(created_at_gteq: "2019-01-01 00:00:00").result
# SELECT users.* FROM users WHERE users.created_at >= '2019-01-01 00:00:00';
_present
User.ransack(name_present: 1).result
# SELECT users.* FROM users WHERE ( users.name IS NOT NULL AND users.name != '' );
# _presentは文字列のカラムのみ使用可能(NOT NULLかつ非空文字)
_blank
User.ransack(name_blank: 1).result
# SELECT users.* FROM users WHERE ( users.name IS NULL OR users.name = '' );
# _blankはNULLまたは空文字
_null
User.ransack(name_null: 1).result
# SELECT users.* FROM users WHERE users.name IS NULL;
_not_null
User.ransack(name_not_null: 1).result
# SELECT users.* FROM users WHERE users.name IS NOT NULL;
_in
User.ransack(name_in: "test").result
# SELECT users.* FROM users WHERE users.name IN ( 'test' );
User.ransack(name_in: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE users.name IN ( 'test', 'hoge' );
_not_in
User.ransack(name_not_in: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE users.name NOT IN ( 'test', 'hoge' );
_lt_any
User.ransack(created_at_lt_any: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at < '2019-01-01 00:00:00' OR users.created_at < '2018-01-01 00:10:00' )
_lteq_any
User.ransack(created_at_lteq_any: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at <= '2019-01-01 00:00:00' OR users.created_at <= '2018-01-01 00:10:00' );
_gt_any
User.ransack(created_at_gt_any: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at > '2019-01-01 00:00:00' OR users.created_at > '2018-01-01 00:10:00' )
_gteq_any
User.ransack(created_at_gteq_any: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at >= '2019-01-01 00:00:00' OR users.created_at >= '2018-01-01 00:10:00' );
_matches_any
User.ransack(name_matches_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test' OR users.name LIKE 'hoge' );
_lt_all
User.ransack(created_at_lt_all: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at < '2019-01-01 00:00:00' AND users.created_at < '2018-01-01 00:10:00' );
_lteq_all
User.ransack(created_at_lteq_all: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at <= '2019-01-01 00:00:00' AND users.created_at <= '2018-01-01 00:10:00' );
_gt_all
User.ransack(created_at_gt_all: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at > '2019-01-01 00:00:00' AND users.created_at > '2018-01-01 00:10:00' );
_gteq_all
User.ransack(created_at_gteq_all: ["2019-01-01 00:00:00", "2018-01-01 00:10:00"]).result
# SELECT users.* FROM users WHERE ( users.created_at >= '2019-01-01 00:00:00' AND users.created_at >= '2018-01-01 00:10:00' );
_matches_all
User.ransack(name_matches_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test' AND users.name LIKE 'hoge' );
_does_not_match_all
User.ransack(name_does_not_match_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE 'test' AND users.name NOT LIKE 'hoge' );
_start
User.ransack(name_start: "test").result
# SELECT users.* FROM users WHERE users.name LIKE 'test%';
_not_start
User.ransack(name_not_start: "test").result
# SELECT users.* FROM users WHERE users.name NOT LIKE 'test%';
_start_any
User.ransack(name_start_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test%' OR users.name LIKE 'hoge%' );
_start_all
User.ransack(name_start_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE 'test%' AND users.name LIKE 'hoge%' );
_not_start_any
User.ransack(name_not_start_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE 'test%' OR users.name NOT LIKE 'hoge%' );
_not_start_all
User.ransack(name_not_start_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE 'test%' AND users.name NOT LIKE 'hoge%' );
_end
User.ransack(name_end: "test").result
# SELECT users.* FROM users WHERE users.name LIKE '%test';
_not_end
User.ransack(name_not_end: "test").result
# SELECT users.* FROM users WHERE users.name NOT LIKE '%test';
_end_any
User.ransack(name_end_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE '%test' OR users.name LIKE '%hoge' );
_end_all
User.ransack(name_end_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE '%test' AND users.name LIKE '%hoge' );
_not_end_any
User.ransack(name_not_end_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE '%test' OR users.name NOT LIKE '%hoge' );
_not_end_all
User.ransack(name_not_end_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE '%test' AND users.name NOT LIKE '%hoge' );
_cont
User.ransack(name_cont: "test").result
# SELECT users.* FROM users WHERE users.name LIKE '%test%' ;
_cont_any
User.ransack(name_cont_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE '%test%' OR users.name LIKE '%hoge%' );
_cont_all
User.ransack(name_cont_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name LIKE '%test%' AND users.name LIKE '%hoge%' );
_not_cont
User.ransack(name_not_cont: "test").result
# SELECT users.* FROM users WHERE users.name NOT LIKE '%test%' ;
_not_cont_any
User.ransack(name_not_cont_any: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE '%test%' OR users.name NOT LIKE '%hoge%' );
_cont_all
User.ransack(name_not_cont_all: ["test", "hoge"]).result
# SELECT users.* FROM users WHERE ( users.name NOT LIKE '%test%' AND users.name NOT LIKE '%hoge%' );
_true
_false
9
12
0

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
9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?