LoginSignup
12
10

More than 5 years have passed since last update.

Ransack で年齢を検索する

Last updated at Posted at 2016-06-18

Ransack は検索機能を簡単なソースコードで実装できる便利な Gem です。
また、Ransack には検索機能を拡張する方法も用意されているので、少し複雑な検索も実装することができます。
今回は年齢を検索する機能を作ってみました。

年齢を検索させる

年齢を検索させると言っても、DBに直接年齢が記録されているケースは少ないと思います。
普通に考えるとDBにはユーザーの生年月日を記録させて、データ取得時に今日の日付から年齢に変換しますよね。

なので、実装的には生年月日を入力してユーザーを検索させるフォームを用意する方がはるかに簡単ですが、
利便性を考えたら検索時にも年齢を入力したくなるはずです。

今回は Ransack の検索機能を拡張して、整数型で受け取った年齢をDate型に変換して検索させるようにしてみます。
結果からいうと以下のような実装になるかと思います。

Ransack での拡張

/config/initializers/ransack.rb
# 生年月日を年齢として検索する。
# xx歳未満
config.add_predicate 'to_age_lt',
  arel_predicate: 'gteq',
  formatter: -> (v) { (v.years.ago + 1.day).to_date },
  type: :integer,
  compounds: false
# xx歳以下
config.add_predicate 'to_age_lteq',
  arel_predicate: 'gteq',
  formatter: -> (v) { ((v + 1).years.ago + 1.day).to_date },
  type: :integer,
  compounds: false
# xx歳以上
config.add_predicate 'to_age_gteq',
  arel_predicate: 'lteq',
  formatter: -> (v) { v.years.ago.to_date },
  type: :integer,
  compounds: false
# xx歳超過
config.add_predicate 'to_age_gt',
  arel_predicate: 'lteq',
  formatter: -> (v) { (v + 1).years.ago.to_date },
  type: :integer,
  compounds: false

使い方

example.rb
# 18歳以上のユーザーを取得する。
User.search(birthday_to_age_gteq: 18).result 

ハマリポイントとしては、誕生日を迎える直前のユーザーの年齢を考慮する点でしょうか。
((v + 1).years.ago + 1.day) という箇所がその対応となっています。

また、年齢としては「○○歳以上」、「○○歳以下」という表現ですが、
生年月日的には「年月日以前」、「年月日以降」という表現になるので、
大小比較の演算子が内部で入れ替わる点も考慮が必要です。

参考

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