LoginSignup
1
2

More than 5 years have passed since last update.

[Rails] 年齢で範囲検索する

Last updated at Posted at 2019-03-04

やりたいこと

誕生日を格納するための Date 型の birthday 列を持つ User モデルがある。ある年齢からある年齢までの User を検索したい。

方法

実装例

次の User モデルで User.by_age として実装している。

class User < ApplicationRecord
  # ある年齢 from からある年齢 to までの User を検索する。
  scope by_age, (lambda do |from: 0, to: 999, today: Date.today|
    # 今日のちょうど to 年前の日付の 1 日後から
    date_from = today.ago((to + 1).years).since(1.day)
    # 今日のちょうど from 年前までを検索する。
    date_to = today.ago(from.years)

    where(birthday: date_from..date_to)
  end)

  # 年齢を (簡易的に) 計算する。
  # TODO: うるう日やうるう秒を考慮する。
  def age(today = Date.today)
    ((today.to_time - birthday.to_time) / 1.year.seconds).floor
  end

  def formatted_birthday
    date = birthday.strftime('%Y/%m/%d')
    wday = %w[日 月 火 水 木 金 土][birthday.wday]

    "#{date} (#{wday})"
  end
end

実行例

zu.png

# (あえて境界値がうるう日前後になるように)
# 今日の日付が 2020/02/29 (土) だと仮定する。
today = Date.parse('2020/02/29')

User.order(:birthday).each do |user|
  puts("#{user.formatted_birthday} #{user.age(today)}#{user.name}")
end
# 1989/02/28 (火) 31 歳 ピカチュウ
# 1989/03/01 (水) 30 歳 カイリュー
# 2000/02/29 (火) 20 歳 ヤドラン
# 2000/03/01 (水) 19 歳 ピジョン

# 20 〜 30 歳の User を検索する。
User.by_age(from: 20, to: 30, today: today).pluck(:name)
#=> ["カイリュー", "ヤドラン"]
1
2
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
1
2