2021年04月04日に参加
学習履歴詳細
Structを使って値の週間集計を行い、描画する
週間の各日付の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まで
Ruby
Rails
2019年09月19日(木)
5.0時間