はじめに
学習記録アプリの開発中、グラフの作成のために1週間分の日付の取得する処理を、「今週」「最後に学習した日の週」「最後に学習した日の前週」の3つそれぞれ記載していました。Rubyでは、メソッドの戻り値を複数返すことができるということなので、3つの処理を1つにまとめていきたいと思います。
環境
- rails 6.0.4.4
- ruby 2.6.5
- chart.js 2.8.0
複数の戻り値を返し方
returnの後にカンマで区切って返す値を記述します。
def calc(a, b)
x = a + b
y = a - b
return x, y
end
a = 20
b = 15
x_1, y_1 = calc(a, b)
puts x_1, y_1
このように、x_1とy_1の変数にそれぞれ値が入っています。
35
5
ちなみに1つの変数に対して、複数の戻り値を代入すると、自動的に配列に変換されます。
正確には、データそのものが配列形式で入るのではなく、データの場所の情報が入り、配列と同じ記述で取り出せるようです。
現在の状況
今週分の日付を取得(週初めの日付、週終わりの日付、1週間分の日付、1週間分の日付のJSON形式、の4つを定義しています)
@b_date = Date.today.beginning_of_week
@e_date = Date.today.end_of_week
week_date = week_date_calc(@b_date, @e_date)
@week_date = week_date.to_json.html_safe
最後に学習した日を含む週の日付を取得
@tb_date = @max_date.beginning_of_week
@te_date = @max_date.end_of_week
week_date = week_date_calc(@tb_date, @te_date)
@week_date = week_date.to_json.html_safe
上記週の1週間前の日付を取得
@lb_date = @max_date.prev_week
@le_date = @max_date.prev_week(:sunday)
week_date = week_date_calc(@lb_date, @le_date)
@week_date_l = week_date.to_json.html_safe
補足
@max_dateは学習記録テーブルで日付の最大値を代入しています。
week_date_calcメソッドは週初めと週終わりの日付を渡して、その間の日付をもつ配列を作成します。
def week_date_calc(b_date, e_date)
w_date = []
s_date = b_date
while s_date <= e_date
w_date << s_date
s_date += 1
end
w_date
end
メソッドを作成
日付を1つ渡して、週初めの日付、週終わりの日付、1週間分の日付、1週間分の日付のJSON形式、の4つのデータを返すメソッドを作成します。
def week_date_set(search_date)
b_date = search_date.beginning_of_week
e_date = search_date.end_of_week
week_date = week_date_calc(b_date, e_date)
week_date_json = week_date.to_json.html_safe
return b_date, e_date, week_date, week_date_json
end
上記、メソッドを使用してコードを書き直していきます。
今週分の日付を取得
@b_date, @e_date, week_date, @week_date = week_date_set(Date.today)
最後に学習した日を含む週の日付を取得
@tb_date, @te_date, week_date, @week_date = week_date_set(@max_date)
上記週の1週間前の日付を取得
@lb_date, @le_date, week_date, @week_date_l = week_date_set(@max_date.weeks_ago(1))
prev_weekメソッドでは前週の週初めを取得してしますので、weeks_agoメソッドに変更しました。
おわりに
これでコードを直す前と同じ動作をするようになりました。
なお、終わった後に気づきましたが、週初めと週終わりの日付は、メソッドで作成した配列から取得すればよかったので、個別で作成する必要はなかったですね。なので、4つの戻り値を返していますが、実際は2つでよかったです。