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

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

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

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

Ruby on Rails

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

Q&A

1回答

4644閲覧

Ruby on Rails でランキング機能

KentoSugita

総合スコア11

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2015/12/04 08:18

編集2022/01/12 10:55

ruby on railsで開発しています。

rails上でランキング機能を実装しようと思っていますが、初心者には少し複雑で悩んでいます。
以下詳細です。

##サービスの内容
ユーザー(大学生)に授業の成績(SやAなど)を登録してもらい、各授業の成績の平均を公開するというものです。(実際は他にも機能あります)
controllerやmodelではS評価は4、A評価は3、B評価は2、C評価は1、D評価は0というように数値で扱います。

そこで「各ユーザーが登録したデータをランキングとして表示する」一連の流れの作成に迷っております。

##今考えている方法
#登録用テーブルとまとめ用テーブルを作成し、同じ授業名をまとめていく
テーブルのカラム(この機能に必要な要素のみ)

登録用

  • name
  • grade(成績評価)

まとめ用

  • name
  • gradeSum
  • count
  1. データが登録さる度に、まとめ用テーブルにも保存
  2. まとめ用テーブルに保存する処理

同名の授業がないかを検索。
既に存在していた場合、成績をそのレコードのgradeSumカラムに足す。(上書き)
存在していなかった場合新たなデータとして追加。(新規追加)
0. そのレコードのcountカラムに、++ を用いて+1ずつ加算していきます。
この数値を用いて平均点を求めるためです。(gradeSum/count=平均点)
0. viewでは、nameとgradeSumとcountから算出される平均点を表示します。

##ご教授を願いたい点
登録用テーブルに保存された時の、同時にまとめ用テーブルの処理もするプログラムです。
具体的には

  • createアクションの際にまとめ用テーブルにも同時に登録するプログラム
  • その時、登録用テーブルのレコードを取り出し、まとめ用テーブルにもsaveするプログラム

拙い説明ですが、ご教授お願いいたします。

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

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

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

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

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

izkn

2015/12/04 08:46

こちらの質問が他のユーザから「質問の範囲が広すぎる」という評価を受けています わからない点を明確にし、調査したこと・試したことと共に記入していただくと、回答が得られやすくなります。
anozon

2015/12/05 01:28

こちらの質問が他のユーザから「質問の範囲が広すぎる」という評価を受けています わからない点を明確にし、調査したこと・試したことと共に記入していただくと、回答が得られやすくなります。
sutonea

2015/12/05 07:00

「登録用テーブル」では何を登録するのかわからないため、テーブル名を修正してください。「まとめ用テーブル」についても同様にお願いいたします。
guest

回答1

0

こういうパターンの場合、集計を別テーブルに入れるのは、あまり筋が良くないと感じます。

大学の成績評価の集計であれば、何万レコードの集計を行う訳ではないので、集計操作の短縮化などの意味はなさそうです。

単純な関連テーブルを作成して、集計はその都度行うのが良いかと。

クラス名など、勝手に想像して書いてみるので、うまい事自分の環境に当てはめて考えてみてください。

Ruby

1# models 2class SchoolClass < ActiveRecord::Base 3 attr_accessor :name 4 has_many :grade_of_classes 5end 6 7class Student < ActiveRecord::Base 8 attr_accessor :name, :student_number, :class_year 9 has_many :grade_of_classes 10end 11 12class GradeOfClass < ActiveRecrod::Base 13 attr_accessor :grade 14 belongs_to :school_class 15 belongs_to :student 16end 17 18# controllers 19# school_class_controllerとstudent_controllerは省略 20class GradeOfClassController < ActionController::Base 21 def new 22 @school_clsses = SchoolClass.all # 成績投入の際の授業一覧 23 end 24 25 def create 26 @grade_of_class = prams[:grade_of_class] 27 # params[:grade_of_class][:school_class_id] 対象クラスのIDを格納 28 # params[:grade_of_class][:grade] 対象クラスの成績を格納 29 @grade_of_class.student = @student # ログイン中の学生はセッション管理ですでにインスタンス化されていると思われ 30 if @grade_of_class.save 31 # レンダラを適当に書く 32 else 33 # 失敗パターンのレンダラを書く 34 end 35 end 36 37 def average_of_classes 38 results = [] 39 SchoolClass.all.each do |sc| 40 results << {class: sc, average: sc.grade_of_classes.average(:grade)} 41 # school_classインスタンスにひも付いているgrade_of_classのgrade平均をArelで取得している 42 end 43 end 44end 45 46# view 47# new, createアクションのビューは省略 48 49# result_of_class/average_of_class.html.erb 50<table> 51 <tr><th>科目名</th><th>平均成績</th><tr> 52 <% @results.each do |result| %> 53 <tr><td><%= result[:class].name %></td><td><%= result[:average] %></td></tr> 54 <% end %> 55</table>

とまあ、こんな感じでしょうか。

後は、授業に年度を入れて、複数年で記録できるようにしたり、
StudentクラスとSchoolClassクラスを関連づけするようにして、
自分が取っている授業のみを入力できるようにするとか、そういう風に発展させてゆけば良いかと思います。

あくまで登録用テーブルと、集計のためのまとめテーブルを利用したいのであれば、
登録用テーブルのcreateアクションのところで、トランザクションを張って更新してあげるのがよいでしょうね。

Ruby

1 def create 2 @grade_of_class = prams[:grade_of_class] 3 # params[:grade_of_class][:school_class_id] 対象クラスのIDを格納 4 # params[:grade_of_class][:grade] 対象クラスの成績を格納 5 @grade_of_class.student = @student # ログイン中の学生はセッション管理ですでにインスタンス化されていると思われ 6 @gradeSum = GradeSum.where(GradeSum.arel_table[:school_class_id].eq(params[:grade_of_class][:school_class_id]).first 7 unless @gradeSum 8 @gradeSum = GradeSum.new 9 @gradeSum.school_class_id = params[:grade_of_class][:school_class_id] 10 end 11 @gradeSum.count += 1 12 @gradeSum.grade_sum += params[:grade_of_class][:grade].to_i 13 ActiveRecord::Base.transaction do 14 @grade_of_class.save! 15 @gradeSum.save! 16 rescue 17 # 失敗パターンのレンダラ 18 end 19 # 成功パターンのレンダラ 20 end

投稿2015/12/08 02:49

編集2015/12/08 02:53
rifuch

総合スコア1901

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問