LoginSignup
15
14

More than 5 years have passed since last update.

ransackで年度検索を実装する

Last updated at Posted at 2017-03-02

ransackを用いて年度検索を実装する.
動作デモはこちら

前提条件

  • Ruby v2.4.0
  • Rails v5.0.2

  • nameとbirthayを持つUserを作成する.

rails g scaffold User name:string birthday:date
  • gemを追加する.
Gemfile
gem 'ransack'

Nameで検索

名前文字列が含まれるかどうかで検索する.
:name_cont の記述がそれに当たる.

app/controllers/users_controller.rb
def index
  @q = User.ransack(params[:q])
  @users = @q.result
end
app/views/users/index.html.erb
<%= search_form_for @q, url: :users do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name_cont, placeholder: 'Name' %>

    <br>
    <%= f.submit 'Search' %>
<% end %>

image

これで生成されるSQLは下記の通り.

# @q.result.to_sql
SELECT "users".* FROM "users" WHERE ("users"."name" LIKE '%A%')

Birthdayを期間で検索

期間の開始・終了を両方選択させるパターン.

app/views/users/index.html.erb
<%= search_form_for @q, url: :users do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name_cont, placeholder: 'Name' %>

    <%= f.label :birthday %>
    <%= f.date_field :birthday_gteq, include_blank: true %> 〜 
    <%= f.date_field :birthday_lteq, include_blank: true %>

    <br>
    <%= f.submit 'Search' %>
<% end %>

image

これで生成されるSQLは下記の通り.
birthday_gteq"birthday" >= '2017-03-01' を指し, birthday_lteq"birthday" <= '2017-03-03' を指す.

# @q.result.to_sql
SELECT "users".* FROM "users" WHERE ("users"."birthday" >= '2017-03-01' AND "users"."birthday" <= '2017-03-03')

Birthdayを年度で検索(年度を選択させるパターン)

期間の開始と終了をしていするのではなく,年度を一つだけ選択して検索したい.
Custom Predicate を作成して,年度(yyyy/04/01-yyyy+1/03/31)で絞込み出来るようにする.

config/initializers/ransack.rb
Ransack.configure do |config|
  config.add_predicate :during_year,
                       arel_predicate: :between,
                       formatter: proc { |v|
                         Time.zone.parse("#{v.year}-4-1").to_date...Time.zone.parse("#{v.year + 1}-4-01").to_date
                         # または `..` で 4/1〜3/31 でもOK
                         # Time.zone.parse("#{v.year}-4-1").to_date..Time.zone.parse("#{v.year + 1}-3-31").to_date
                       },
                       type: :date
end

Custom Predicate は, <field name>_<custom_predicate_name> で使用できる.

app/views/users/index.html.erb
<%= search_form_for @q, url: :users do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name_cont, placeholder: 'Name' %>

    <%= f.label :birthday %>
    <%= f.date_field :birthday_gteq, include_blank: true %> 〜 
    <%= f.date_field :birthday_lteq, include_blank: true %>

    <%= f.label :birthday_during_year %>
    <%= f.date_select :birthday_during_year,
                      discard_day: true, discard_month: true,
                      include_blank: true %>

    <br>
    <%= f.submit 'Search' %>
<% end %>

image

これで生成されるSQLは下記の通り.

# @q.result.to_sql
SELECT "users".* FROM "users" WHERE ("users"."birthday" >= '2016-04-01' AND "users"."birthday" < '2017-04-01')

参考

15
14
2

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
15
14