#1. Rubyを使用した表現について
カレンダーアプリで特定のイベントの一週間分の日毎の回数をグラフで表す際のバックエンド側の処理を実装しています。
以下rubyまたはactive recordのメソッドでEventテーブルから特定のiconの条件にマッチするstartの時間を取り出してその数を直近一週間分を日毎にカウントし歯抜け部分には0で埋めるようにするテーブルの作成を考えいています。
具体的には以下のようになります。(startのデータの型はdatetimeとなり,event作成の際に日付を整形しております。)
元のテーブル
[["07-07", 1], ["07-08", 3], ["07-09", 0], ["07-10", 2], ["07-11", 2], ["07-12", 1], ["07-13", 0]]
みたいな配列でデータが欲しいです。
rubyのメソッドで
@milk = Event.order('start').where(icon: 'milk.png').pluck(:start).group_by { |start| I18n.l(start) } .map do |date,array| [date, array.count] end
と書いて日付範囲の指定なしで該当する日付のカウントをとるところまではできておりますが、日付の連番の仮想テーブルの作成とleft join をruby表現できず、以下の通りsqlを生で書いて対応しております。
解決策が分かる方はよろしくお願いします。
なお、postgereSQLでは以下のように書いてます。
SELECT d.start_date, coalesce(r.count, 0) AS count FROM ( SELECT to_char(s.a, 'MM-DD') AS start_date FROM ( SELECT * FROM generate_series(current_timestamp + '-6 days', current_timestamp, '1 day'::interval) ) AS s(a) ) AS d LEFT JOIN ( SELECT to_char(start,'MM-DD') AS start_date, count(*) FROM events WHERE icon='milk.png' GROUP BY to_char(start,'MM-DD'), icon ) AS r ON d.start_date = r.start_date
2.Rails上でpostgereSQLを使った場合のメソッドの書き方
実際にrailsに書くと以下のような感じとなりました。
event.rb
private def self.milk_count sql = <<-"EOS" SELECT d.start_date, coalesce(r.count, 0) AS count FROM ( SELECT to_char(s.a, 'MM-DD') AS start_date FROM ( SELECT * FROM generate_series(current_timestamp + '-6 days', current_timestamp, '1 day'::interval) ) AS s(a) ) AS d LEFT JOIN ( SELECT to_char(start,'MM-DD') AS start_date, count(*) FROM events WHERE icon='milk.png' GROUP BY to_char(start,'MM-DD'), icon ) AS r ON d.start_date = r.start_date EOS ActiveRecord::Base.connection.select_all(sql) end
events_controller.rb
def statics result = Event.milk_count @milk_count = result::rows end
一応配列は取れるのですが、これが正しいやり方なのかわかりません。おかしい点がありましたらご指摘お願いします。