週間の各日付のDateオブジェクトと、集計したいカラムのシンボルを受け取って、値を探して返すメソッドの定義。
(例えば、7/2のactivityカラムを指定すると, -2が返る)
activerecordのselectメソッドではオブジェクトが返ってしまい値を返せなかった。調べる中でpluckメソッドが適当だと分かった。
アプリ制作
実現したいこと
StatisticコントローラでDiaryの週間集計をする。
週間の各コンディションの値を下のようなテーブルにしたい。
そして配列にしてChart.jsに渡したい。
From: September 15
To: September 21
どうすればこのテーブルを作れるのか?
Statistic Pathのリンクをクリック
Date.todayから週の初めの日、週の終わりの日を算出する
Range(週の初め..週の終わり).to_a でlabel(グラフの横軸)が出来上がる。
labelとカラムから各カラムの値の配列を返す
戻り値用の配列を初期化
labelの配列とカラムを引数にとる
labelから日付を1つずつ取り出し、その日のDiaryレコードを検索
Diary.カラムで値を取り出して戻り値用の配列につっこむ
labelと各カラムの配列を返す
StatisticControllerの実装
class StatisticsController < ApplicationController
before_action :require_user_logged_in, :set_current_user
WeeklyReport = Struct.new(
:date_from,
:date_to,
:labels,
:activity_array,
:mood_array,
:appetite_array
)
def index
activity = 'activity'
@weekly_report = WeeklyReport.new.tap do |r|
r.date_from = Date.today.beginning_of_week
r.date_to = Date.today.end_of_week
r.labels = week_dates
r.activity_array = array_generator(week_dates, :activity)
r.mood_array = array_generator(week_dates, :mood)
r.appetite_array = array_generator(week_dates, :appetite)
end
end
private
def week_dates
today = Date.today
(today.beginning_of_week..today.end_of_week).to_a
end
def array_generator(week_dates, colmun)
week_dates.map do |date|
current_user.diaries.where(diary_date: date).pluck(colmun)[0]
end
end
end
週間集計のテーブルを描画できた。
次は、これをChart.jsに渡してグラフにする。
分からないところ
tapメソッド
# tapメソッドは、ブロック変数にレシーバ自身を代入してブロックを実行する。
# 戻り値はレシーバ自身
"hello".bytes.to_a.tap {|arr| p arr }
# "hello".bytes.to_a
# => [104, 101, 108, 108, 111]
# このArrayがブロック引数(|arr|)に入る。
# そして p arr が実行される。
# 戻り値はレシーバ自身なので、Arrayが返る。
"hello".bytes.to_a.tap {|arr| p arr }.collect {|byte| byte.to_s(16) }.tap {|arr| p arr }
# つまり...
[104, 101, 108, 108, 111].collect {|byte| byte.to_s(16) }.tap {|arr| p arr }
# mapのエイリアスなので、Arrayを一つずつブロック引数に入れて、ブロックを実行
[104, 101, 108, 108, 111].collect {|byte| byte.to_s(16) }
# => ["68", "65", "6c", "6c", "6f"]
# つまり...
["68", "65", "6c", "6c", "6f"].tap {|arr| p arr }
# レシーバがブロック引数に代入され、ブロックが実行される
p ["68", "65", "6c", "6c", "6f"]
# 戻り値はレシーバ自身 => ["68", "65", "6c", "6c", "6f"]
# 1行にできるのはわかったけど、逆に読みにくいのでは?笑
Rubyのレファレンスを読んで意味をつかんだ。
プロを目指す人のRuby入門
正規表現
初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」
初心者歓迎!手と目で覚える正規表現入門・その2「微妙な違いを許容しつつ置換しよう」
最後の方の解決策2まで