質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

2258閲覧

Rails 1対多関係にあるテーブルカラムの値を取り出し、合算したものをViewで表示させたい

ikutyan46

総合スコア18

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/06/16 12:33

編集2020/06/16 13:26

##【実現したい事】
①1対多の関係にあるテーブルがあり、子関係にあるテーブルのカラムの値を取り出したい
②取り出したものをsum関数などで計算し、合算した値を、View上で表示させたい(=赤枠部分の合計練習時間を表示させたい)

イメージ説明

##【環境】
※未経験からエンジニア転職を目指してオリジナルアプリを開発中の者です(学習期間約2ヶ月程度)。
・Ruby:2.6.5
・Rails:5.2.4.3
・DB設計 ※詳細は下記コード
親:Recordテーブル
子:Practiceテーブル

##【試した事】
①Controllerのindexアクションに、total_practice_timeという新しい変数を宣言し、子レコード(Practiceテーブル)モデルの配列「:practices」を代入させる

②次の処理で、ブロック引数|total|を定めて、格納されているpractice_timeの値を全て足し算したものを結果として取り出す処理をする

しかし、「Syntax error」と出ており、何をどう直すべきか分からないため、ご意見・アドバイスを頂戴できますと幸いです。

RecordsController

1class RecordsController < ApplicationController 2before_action :authenticate_user! 3 4 def index 5 @records = current_user.records.includes(:practices).page(params[:page]).per(8) 6 total_practice_time = Record.includes(:practices) 7 total_practice_time.each do |total| 8 total.sum(:practice_time) 9 end 10 @q = Record.ransack(params[:q]) 11 @search_records = @q.result(distinct: true) 12 end 13 14 def show 15 @record = Record.find(params[:id]) 16 end 17 18 def new 19 @record = Record.new 20 output = @record.outputs.build 21 practice = @record.practices.build 22 task = @record.tasks.build 23 end 24 25 def create 26 @record = Record.new(record_params) 27 logger.info "###### #{@record.inspect}" 28 if @record.save 29 flash[:success] = "練習内容の登録が完了しました。" 30 redirect_to records_url 31 else 32 flash[:alert] = "登録に失敗しました。" 33 render :new 34 end 35 end 36 37 def edit 38 @record = Record.find_by(id: params[:id]) 39 end 40 41 def update 42 @record = Record.find_by(id: params[:id]) 43 if @record.update(record_params) 44 flash[:success] = "練習内容の更新が完了しました。" 45 redirect_to records_url 46 else 47 flash[:alert] = "更新に失敗しました。" 48 render :edit 49 end 50 end 51 52 def destroy 53 record = Record.find_by(id:params[:id]) 54 record.destroy 55 56 redirect_to root_path, notice: "練習記録を削除しました。" 57 end 58 59 def aggregate_result 60 @record = Record.find(params[:id]) 61 gon.data = Record.where(params[:practice_time]) 62 6.times do 63 # gon.data << rand(100.0) 64 end 65 end 66 67 private 68 69 def set_user 70 @user = current_user || User.new 71 end 72 73 def record_params 74 params.require(:record).permit(:record_id, :training_date, :learning_point, outputs_attributes:[:output_name, :id], practices_attributes:[:practice_item, :practice_time, :id], tasks_attributes:[:task_name, :id]).merge(user_id: current_user.id) 75 end 76 77end

slim

1 2h1 練習記録一覧 3.container 4 .row 5 .col-sm-6 6 .form-group 7 = form_with model: @record do |f| 8 = f.date_field :training_date 9 10table.table-hover.table-respnsive 11 thead 12 tr 13 th 練習日 14 th 登録日時 15 th 総練習時間 16 th 17 th 18 tbody 19 - @records.each do |record| 20 - record.practices.each do |practice| 21 tr 22 td= link_to record.training_date, record_path(record) 23 td= record.created_at 24 td= total 25 / td= practice.practice_time 26 td 27 = link_to '編集する', edit_record_path(record), class: 'btn btn-primary mr-3' 28 = link_to '削除する', record_path(record), method: :delete, data: { confirm: "練習記録を削除します。よろしいですか?" }, class: 'btn btn-danger'

##【コード】

recordmodel

1 2class Record < ApplicationRecord 3 validates :learning_point, presence: true 4 validates :training_date, presence: true 5 6 belongs_to :user 7 has_many :practices, dependent: :destroy 8 accepts_nested_attributes_for :practices 9end 10Practiceモデル 11 12class Practice < ApplicationRecord 13 validates :practice_item, presence: true 14 validates :practice_time, presence: true 15 belongs_to :record 16end

shema

1 2ActiveRecord::Schema.define(version: 2020_05_25_064157) do 3 4 create_table "records", force: :cascade do |t| 5 t.string "user_id" 6 t.text "learning_point" 7 t.date "training_date" 8 t.datetime "created_at", null: false 9 t.datetime "updated_at", null: false 10 end 11 12 create_table "practices", force: :cascade do |t| 13 t.string "practice_item" 14 t.integer "practice_time" 15 t.bigint "record_id" 16 t.datetime "created_at", null: false 17 t.datetime "updated_at", null: false 18 t.index ["record_id"], name: "index_practices_on_record_id" 19 end

#エラーメッセージと画像
~~再開したところ、Syntaxerrorでした。
~~
→indexアクションに、1つ余分にendが入っていたことに気づいたので修正しました。すると、下記のログと画像を確認しました。

sumメソッドが提示されていませんと怒られています。。。

log

1Started POST "/__better_errors/c4bbb4c567585e78/variables" for ::1 at 2020-06-16 22:19:03 +0900 2Started GET "/records?utf8=%E2%9C%93&q%5Btraining_date_eq%5D=&commit=%E7%B7%B4%E7%BF%92%E6%97%A5%E3%81%A7%E6%A4%9C%E7%B4%A2" for ::1 at 2020-06-16 22:19:04 +0900 3Processing by RecordsController#index as HTML 4 Parameters: {"utf8"=>"✓", "q"=>{"training_date_eq"=>""}, "commit"=>"練習日で検索"} 5 User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 3], ["LIMIT", 1]] 6 ↳ /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 7 Record Load (0.3ms) SELECT "records".* FROM "records" 8 ↳ app/controllers/records_controller.rb:7 9 Practice Load (0.5ms) SELECT "practices".* FROM "practices" WHERE "practices"."record_id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $40, $41) [["record_id", 1], ["record_id", 2], ["record_id", 3], ["record_id", 4], ["record_id", 5], ["record_id", 6], ["record_id", 7], ["record_id", 8], ["record_id", 9], ["record_id", 10], ["record_id", 11], ["record_id", 12], ["record_id", 13], ["record_id", 14], ["record_id", 15], ["record_id", 16], ["record_id", 17], ["record_id", 18], ["record_id", 19], ["record_id", 23], ["record_id", 24], ["record_id", 25], ["record_id", 26], ["record_id", 27], ["record_id", 28], ["record_id", 29], ["record_id", 30], ["record_id", 31], ["record_id", 32], ["record_id", 33], ["record_id", 34], ["record_id", 35], ["record_id", 36], ["record_id", 37], ["record_id", 38], ["record_id", 39], ["record_id", 40], ["record_id", 41], ["record_id", 62], ["record_id", 63], ["record_id", 64]] 10 ↳ app/controllers/records_controller.rb:7 11Completed 500 Internal Server Error in 38ms (ActiveRecord: 9.7ms) 12 13 14 15NoMethodError - undefined method `sum' for #<Record:0x00007ffaf6c1acc0>: 16 app/controllers/records_controller.rb:8:in `block in index' 17 app/controllers/records_controller.rb:7:in `index' 18 19Started POST "/__better_errors/28783482a38955a1/variables" for ::1 at 2020-06-16 22:19:04 +0900 20 Record Load (0.3ms) SELECT "records".* FROM "records" WHERE "records"."user_id" = $1 LIMIT $2 OFFSET $3 [["user_id", "3"], ["LIMIT", 8], ["OFFSET", 0]] 21 ↳ /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 22 Practice Load (1.2ms) SELECT "practices".* FROM "practices" WHERE "practices"."record_id" IN ($1, $2, $3) [["record_id", 62], ["record_id", 63], ["record_id", 64]] 23 ↳ /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 24 CACHE Record Load (0.0ms) SELECT "records".* FROM "records" WHERE "records"."user_id" = $1 LIMIT $2 OFFSET $3 [["user_id", "3"], ["LIMIT", 8], ["OFFSET", 0]] 25 ↳ /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 26 CACHE Practice Load (0.0ms) SELECT "practices".* FROM "practices" WHERE "practices"."record_id" IN ($1, $2, $3) [["record_id", 62], ["record_id", 63], ["record_id", 64]] 27 ↳ /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 28

イメージ説明

##最初に質問していた時のエラーメッセージと画像

log

1Started GET "/" for ::1 at 2020-06-16 21:56:55 +0900 2 3SyntaxError - syntax error, unexpected end, expecting end-of-input: 4 app/controllers/records_controller.rb:80:in `' 5 6Started POST "/__better_errors/cbfc53cbe6b50718/variables" for ::1 at 2020-06-16 21:56:56 +0900 7Started GET "/" for ::1 at 2020-06-16 21:56:57 +0900 8 9SyntaxError - syntax error, unexpected end, expecting end-of-input: 10 app/controllers/records_controller.rb:80:in `' 11 12Started POST "/__better_errors/66effe8f5f8cef8c/variables" for ::1 at 2020-06-16 21:56:57 +0900

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2020/06/16 12:45

そのエラーメッセージをを載せてください。 回答に重要な情報が詰まってますので
ikutyan46

2020/06/16 13:05

早速ありがとうございます!!先ほどエラーメッセージと画像添付しました。念のためご確認頂ければ幸いです。
winterboum

2020/06/16 13:08

そのエラーは endのとじ方がおかしい、というものですので、controller全体がないとわからないですね
ikutyan46

2020/06/16 13:28

ご丁寧にありがとうございます。Syntax errorは、indexアクションの「end」を1つ多くつけていたために発生していたことを確認しました。 それを消して新しいエラー(No method)が発生しましたので、Controllerも全部載せて変更しました。恐れ入りますが、今一度ご確認頂ければ幸甚です。
winterboum

2020/06/16 14:26

そこで、回答の所に進みます
guest

回答1

0

ベストアンサー

方向は合っていそうです。
ただ、変数の命名は注意しましょう。
名前から何であるのかがわかるようにする。
勘違いしないようにする
total_practice_time = Record.includes(:practices)
得られるものは (複数の)Practceですから、
practices = Record.includes(:practices)
に。
total.sum(:practice_time)のsumはArrayにならありますが、totalすなわちPracticeに定義してありますか?多分無いですよね
sum(:practice_time)の書き方はSQL関数っぽい。。SQLで求めさせることもできますが、ruby、RAILSのわざと言うよりSQLの技になるのでそれはあとにまわしてruby、RAILSでやるとすると

total_practice_time = 0 practices.each{|practice| total_practice_time += practice.practice_time }

というのをスマートに書くと

total_practice_time = practices.inject(0){|sum,practice| sum + practice.practice_time }

ただこれですと全員の合計になってしまいますね。
(というところまで進めてから、より欲しい機能に修正しましょう)

投稿2020/06/16 13:01

winterboum

総合スコア23347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikutyan46

2020/06/17 07:36

winterboumさん、ありがとうございます。一度、やってみます^^
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問