#実現したいこと
Railsでグループ単位で値を集計(SUM)し、各グループごとの集計結果をControllerで変数として定義したい
※その後、定義した変数について、gem gonを活用してJavaScriptに定義した値を加える予定です。
#環境・条件
・Ruby:2.6.5
・Rails:5.2.4.3
・DB:PostgreSQL
・DB設計 ※詳細は下記コード
親:Recordテーブル(属性:id,その他)
子:Practiceテーブル(属性:id,practice_item, practice_time)
※practice_itemで格納される値は、string型かつ決まった文字列
#試したこと
###構想
★ゴール:chart.jsにRuby変数を組み込んで変数の値をaggrigate_results.html.slimに表示させること
★そのために必要となる要素
全てのRecordテーブルのレコードから、practice_itemごとに格納されている全てのpractice_timeの値を合計したものをオブジェクトとすること
★そのために必要な実装
1.全てのrecordを取り出す
2.全てのrecordが取り出せたら、PracticeテーブルのPractice_itemを分類して棲み分けさせる
3.棲み分けしたpractice_itemの全てのpractice_timeの値をsumメソッドなどで合計値を計算し、それをまた1つのオブジェクトとする
4.practice_itemごとの合計値が含まれる集合を、ハッシュか配列で定義する
5.定義したハッシュか配列をViewで表示できるようJSを修正する
★1.2.3を実施(=Practiceテーブルにある、practice_item,practice_timeを両方検索して取り出す。その後practice_timeをSUM関数で集計)
Controller
def aggregate_result @record = current_user.records.includes(:practices).select("practice_item", "practice_time").group("practice_item").sum(:practice_time) logger.info "test #{@record}" gon.data = @record end
それでログを確認したところ、下記の通りとなったのですが、その後4.5.をどのようにすれば良いのか?ご教授頂ければ幸いです。
※現時点の内容を画面確認しましたが、エラーにはなっていないものの、表示はされていないです。
もしくは、やり方が違うのでは?と言うものがあれば、遠慮なく仰って頂ければ幸いです。
log
started POST "/__better_errors/1d27c32fbb9084fd/variables" for ::1 at 2020-06-20 23:40:45 +0900 Started GET "/records/3/aggregate_result" for ::1 at 2020-06-20 23:40:46 +0900 Processing by RecordsController#aggregate_result as HTML Parameters: {"id"=>"3"} User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 3], ["LIMIT", 1]] ↳ /Users/user/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-5.2.4.3/lib/active_record/log_subscriber.rb:98 (0.6ms) SELECT SUM(practice_time) AS sum_practice_time, practice_item AS practice_item FROM "records" LEFT OUTER JOIN "practices" ON "practices"."record_id" = "records"."id" WHERE "records"."user_id" = $1 GROUP BY practice_item [["user_id", "3"]] ↳ app/controllers/records_controller.rb:57 test {"多球練習"=>222, "サーブ練習"=>170, "フットワーク"=>30, "オール"=>22, "台上処理"=>120} Rendering records/aggregate_result.html.slim within layouts/application Rendered records/_flash_messages.html.slim (2.0ms) Rendered records/aggregate_result.html.slim within layouts/application (6.1ms) Rendered records/_header.html.slim (3.1ms) Rendered records/_footer.html.slim (1.6ms) Completed 200 OK in 51ms (Views: 29.4ms | ActiveRecord: 5.2ms)
#コード
Controller
class RecordsController < ApplicationController before_action :authenticate_user! def index @q = current_user.records.ransack(params[:q]) @search_records = @q.result(distinct: true).includes(:practices).page(params[:page]).per(8) end def show @record = Record.find(params[:id]) end def new @record = Record.new output = @record.outputs.build practice = @record.practices.build task = @record.tasks.build end def create @record = Record.new(record_params) logger.info "###### #{@record.inspect}" if @record.save flash[:success] = "練習内容の登録が完了しました。" redirect_to records_url else flash[:alert] = "登録に失敗しました。" render :new end end def edit @record = Record.find_by(id: params[:id]) end def update @record = Record.find_by(id: params[:id]) if @record.update(record_params) flash[:success] = "練習内容の更新が完了しました。" redirect_to records_url else flash[:alert] = "更新に失敗しました。" render :edit end end def destroy record = Record.find_by(id:params[:id]) record.destroy redirect_to root_path, notice: "練習記録を削除しました。" end def aggregate_result @record = current_user.records.includes(:practices).select("practice_item", "practice_time").group("practice_item").sum(:practice_time) logger.info "test #{@record}" gon.data = @record end private def set_user @user = current_user || User.new end def record_params params.require(:record).permit(:record_id, :training_date, :learning_point, outputs_attributes:[:output_name, :id, :_destroy], practices_attributes:[:practice_item, :practice_time, :id, :_destroy], tasks_attributes:[:task_name, :id, :_destroy]).merge(user_id: current_user.id) end end
schema.rb(一部)
ActiveRecord::Schema.define(version: 2020_05_25_064157) do create_table "practices", force: :cascade do |t| t.string "practice_item" t.integer "practice_time" t.bigint "record_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["record_id"], name: "index_practices_on_record_id" end create_table "records", force: :cascade do |t| t.string "user_id" t.text "learning_point" t.date "training_date" t.datetime "created_at", null: false t.datetime "updated_at", null: false end
aggregate_result.html.slim
= render 'records/flash_messages' h1 レポート canvas#myPieChart script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js" javascript: var ctx = document.getElementById("myPieChart"); var myPieChart = new Chart(ctx, { type: 'pie', data: { labels: ["サーブ練習", "フットワーク", "3球目攻撃", "台上処理","多球練習","オール"], datasets: [{ backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(242,68,172,0.2)' ], data: gon.data }] }, options: { title: { display: true, text: '練習内容の内訳' } } }); = link_to '一覧に戻る', root_path, class: 'btn btn-primary'
あなたの回答
tips
プレビュー