経緯
誕生日情報を持ったDBより"今月が誕生日のユーザー"を抽出したくて調べた際の忘備録です。
環境
Ruby 2.3.0
Rails 5.0.4
Database Postgresql
参考
stackoverflow: ActiveRecord Find By Year, Day or Month on a Date field
例
schema.rb
create_table "users", force: :cascade do |t|
t.string "name"
t.datetime "birthday"
end
↑こんな感じのDBから今月の誕生日のユーザーの一覧を表示したいという感じです。
SQL関数を利用して抽出する
SQLの日付関数の"EXTRACT"関数を利用して抽出できました。
EXTRACT
EXTRACT(日付 FROM 日付)
※SQLの日付関数はDBMSによって実装がバラバラらしいので利用しているDatabaseによってはうまく抽出できないかもしれません。 EXTRACT関数は"Postgresql"と"Mysql"では利用可能な様子です。日付データからその一部分、たとえば「年」や「月」、または「時間」や「秒」だけを切り出す場合に使用。戻り値は日付型ではなく数値型になる。
SQLで書くと下記のような感じです。
SELECT CURRENT_TIMESTAMP,
EXTRACT(YEAR FROM CURRENT_TIMESTAMP) AS year,
EXTRACT(MONTH FROM CURRENT_TIMESTAMP) AS month,
EXTRACT(DAY FROM CURRENT_TIMESTAMP) AS day,
EXTRACT(HOUR FROM CURRENT_TIMESTAMP) AS hour,
EXTRACT(MINUTE FROM CURRENT_TIMESTAMP) AS minute,
EXTRACT(SECOND FROM CURRENT_TIMESTAMP) AS second;
実行結果
now | year | month | day | hour | minute | second |
---|---|---|---|---|---|---|
2017-12-07 09:45:33.987+09 | 2017 | 12 | 7 | 9 | 45 | 33.987 |
Railsでは、上記を参考にしてActiveRecordのwhereメソッドを利用して誕生日月のユーザーを抽出します。
controllers/users_controller.rb
class UsersController < ApplicationController
def index
// 現在の日時の月
now_month = Time.now.month
@birtyday_users = User.where('extract(month from birthday) = ?', now_month)
end
end
画面に描画します。
views/users/index.html.erb
<h1>今月誕生日のユーザー</h1>
<% if @birtday_users.any? %>
<dl>
<% @birthday_users.each do |user| %>
<!-- 見やすいように表示を整えてます -->
<dt><%= user.birthday.strftime('%m月%d日') %></dt>
<dd><%= user.name %></dd>
<% end %>
</dl>
<% end %>
こんな感じで今月の誕生日のユーザーの一覧を描画できました。
EXTRACT関数を使用すれば用途に応じて"年"や"日"毎でデータを抽出して利用できそうです。