はじめに
期間を絞ってデータをいじくりたいあなたに。
Railsアプリケーション作成時、**「もっと早く知っていれば!」**と後悔したメソッドたちの紹介です。
この記事が役に立つ方
- ActiveSupportの存在をあまり認識せずに
- Ruby on Railsアプリケーションを作成している
- Rails初心者
この記事のメリット
- 「きっと誰かがこの操作のメソッド作ってるよね!先に用意されていないか探そう。」という思考になることが出来る。
- 期間指定で工数の削減が出来るようになる。
環境
- OS: macOS Mojave version 10.14.6
- シェル: zsh
- Ruby 2.6.3
- Rails 6.0.1
背景
投稿の背景は以下の通りです。
自作の学習時間記録アプリにて日、週、月それぞれで範囲指定をして計算したいシーンに遭遇。
↓
DBに専用のカラムを設けたり、変数を沢山作ったりして実装。ムダが多い気がしてリファクタリング方法を探す。
↓
実装後、ActiveSupportに超便利メソッドがあることが発覚。工数のムダに超ショックを受ける。
↓
反省してQiita投稿することにしました。
各メソッドの紹介
前提
-
rails console
で実行 - gem
pry-rails
を使用
$ rails c
Running via Spring preloader in process 8066
Loading development environment (Rails 6.0.1)
基準となる変数now
は以下のようにして、予め用意します。
now = Time.current
↓
Thu, 07 Nov 2019 14:15:57 UTC +00:00
all_day
【出力】今日の日付で、00:00:00から23:59:59まで
now.all_day
↓
Thu, 07 Nov 2019 00:00:00 UTC +00:00..Thu, 07 Nov 2019 23:59:59 UTC +00:00
all_week
【出力】月曜始まりで、その日を含む週の全範囲。
now.all_week
↓
Mon, 04 Nov 2019 00:00:00 UTC +00:00..Sun, 10 Nov 2019 23:59:59 UTC +00:00
all_month
【出力】その日を含む月の全範囲。2月など、日数が少なくても、うるう年でも自動で算出してくれる。
now.all_month
↓
Fri, 01 Nov 2019 00:00:00 UTC +00:00..Sat, 30 Nov 2019 23:59:59 UTC +00:00
all_year
【出力】その日を含む年の全範囲。
now.all_year
↓
Tue, 01 Jan 2019 00:00:00 UTC +00:00..Tue, 31 Dec 2019 23:59:59 UTC +00:00
活用例
その週の累計学習時間を算出したい
冗長すぎてお恥ずかしい限りですが、比較対象として元の自分のコードを掲載します。
####【Before】11行
@today = Date.today # 今日の日付を変数に代入
@daily_records = DailyRecord.all # 日別の記録テーブルを全て変数に代入
@day_of_week = @today.cweek # 今日の日付の曜日を変数に代入
case @day_of_week
when 0 # デフォルトでは日曜が"0"で土曜が"6"
@day_of_week = 6 # 月曜はじまりにしたいので、日曜を"6"とする
else
@day_of_week - 1 # それ以外の曜日は月曜はじまりにするために1つずらす
end
@weekly_records = @daily_records.limit(7).order('id DESC') # 直近の日別記録を最新のものから7日分抽出し、変数に代入
@weekly_min = @weekly_records.where(days_of_week: 0..@thisweek).sum(:daily_total) # 月曜から今日までの学習時間(daily_totalが日別の学習時間を表すのカラム)を合計する
これを、先程のall_week
を活用して書き換えたのが以下コードです。
なんということでしょう!たったの3行!7行も削減!
しかも何をやっているのか分かりやすい。
####【After】3行
@today = Date.today
@daily_records = DailyRecord.all
@weekly_min = @daily_records.where(date: @today.all_week).sum(:daily_total)
おわりに
工数の無駄に超ショックを受けつつも、またひとつ勉強になりました!
自分が考えること
||
先人が既に考えている
||
「メソッドとして用意されている」
今後はまず、「これ、解決出来るメソッドあるんじゃないか?」と考えてムダを省くクセをつけていきます。
参考にさせて頂いたサイト(いつもありがとうございます)
Rails開発をもっと楽しくする便利メソッド集 - 動かざることバグの如し
Active Support コア拡張機能 - Rails ガイド