I want to take out the values of the columns in the Rails Controller 1-to-Multiple relationship table and display the sum in View.

Asked 2 years ago, Updated 2 years ago, 38 views

】What I want to realize したい
①You want to retrieve the values of columns in tables that have a one-to-many relationship and that have a child relationship.
②I want to add up what I took out and display it in View (=I want to display the total practice time of the red frame)

Enter a description of the image here

[Environment] *I am developing an original application to change jobs as an engineer (study period is about 2 months).
·Ruby: 2.6.5
·Rails: 5.2.4.3
·DB design *For details, please refer to the following code
parent:Record table
children:Practice table

試Trial 】
①Declare a new variable called total_practice_time for the controller index action and place an array of child record (practice table) models の:practices を

次 In the following process, the block argument |total| is determined, and the result is taken out by adding all the stored practice_time values.

"However, it says ""Syntax error"" and I don't know what to fix, so I would appreciate your feedback and advice."

records_controller.rb

def index
    @records=current_user.records.includes(:practices).page(params[:page]).per(8)

    total_practice_time = Record.includes(:practices)
      total_practice_time.each do | total |
        total.sum(:practice_time)
      end
    end

index.html.slim

h1 Practice Record List
.container
  .row
    .col-sm-6
      .form-group
        = form_with model —@record do | f |
          = f.date_field —Training_date

table.table-hover.table-responsive
  thead
    tr
      th practice day
      th Registration date and time
      th Total practice time
      th
      th
  tbody
    - @ records.each do | record |
      - record.practices.each do | practice |
        tr
          td=link_to record.training_date, record_path(record)
          td = record.created_at
          td = total
          / td = practice.practice_time
          td
            = link_to 'Edit', edit_record_path(record), class: 'btn btn-primary mr-3'
            = link_to 'Delete', record_path(record), method::delete, data:{confirm:"Delete practice record.Would that be all right?" },class: 'btn btn-danger'

[Code]

Record Model

class Record <ApplicationRecord
  values:learning_point,presence:true
  values:training_date, presence:true

  belongs_to —user
  has_many:practices, dependent::destroy
  accepts_nested_attributes_for —practices
end

Practice Model

class Practice <ApplicationRecord
  values:practice_item,presence:true
  values:practice_time, presence:true
  belongs_to —record
end

shema.rb

ActiveRecord::Schema.define(version:2020_05_25_064157)do

  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

  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

ruby-on-rails ruby

2022-09-30 20:18

2 Answers

Good evening.

I read the question roughly.
What I want to do is to show the total practice_time of the child model practice side by side on the record list.
If so, what do you think about the following way to write in the view side index.html.slim?

tbody
    - @ records.each do | record |
      tr
        td=link_to record.training_date, record_path(record)
        td = record.created_at
        td = record.practices.sum(:practice_time)

I think there are many other ways to realize it, but I think the above is somewhat simple.
I'm sorry if it's different from what I want to do!


2022-09-30 20:18

The Syntax Error itself is probably occurring at the bottom.At first glance, Record.includes(:practices) alone does not start the block. You need do...end or {...}.

total_practice_time=Record.includes(:practices)
  total_practice_time.each do | total |
    total.sum(:practice_time)
  end
end

Also, the total_practice_time.each inside seems suspicious.

If you want to calculate the total, I think it would be simple to take a sum as a model.The method is created in the Record model and referenced in the view as shown below.Also, if it is this simple, it would be good to calculate it in the view like Awakichi's answer.

default_practice_time
  practices.sum(:practice_time)
end

ただし Note, however, that this is an N+1 query.Depending on the amount of data, you may need to fix it.


2022-09-30 20:18

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.