Help us understand the problem. What is going on with this article?

Ransack で年齢を検索する

More than 3 years have passed since last update.

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) という箇所がその対応となっています。

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

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away