LoginSignup
17

More than 3 years have passed since last update.

【知らずに損した】ActiveSupportの期間指定メソッドall_day, all_week, all_month, all_year

Last updated at Posted at 2019-11-07

はじめに

期間を絞ってデータをいじくりたいあなたに。

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で実行
  • gempry-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 ガイド

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
17