Day 10: DB へ情報入力、ページに出力
/
from Qiita: マスターデータ(DBへ情報入力、ページに出力
Environment
仮想環境 OS: Ubuntu 18.04 Ruby:2.51 Rails:5.2.2
流れ
- 中間テーブルにデータ入力
- 性別の 0 or 1 の表記を、male or female に変更
- Student の show ページに、生徒ごとの試験結果など、データを出力
実段階
生徒データと関連付けするときは
student1 = Student.firststudent1.clubs << Club.firststudent1.save
データ入力
id1 から id100 までの生徒に、0 から 4 個の部活(選択肢は 13 部)に入ってもらう。
(1..100).each do |i| student = Student.find(i) 1.upto(rand(0..4)) do student.clubs << Club.find(rand(1..13)) student.save endend
生徒の試験結果情報 id100 までの生徒に、9 科目の試験を受けてもらう。
(1..100).each do |i| student = Student.find(i) 1.upto(9) do |num| sub = Subject.find(num) exam_res = ExamResult.new exam_res.name = "試験#{num}" exam_res.score = rand(1..sub.max_score) exam_res.subject = sub student.exam_results << exam_res student.save endend
Studentsのindexページの表記を変更
enum gender: { male: 0 ,female: 1}enum age: {"teen": 0, "twenty": 1}
<div class="field"> <%= form.label :gender %> <%= form.radio_button :gender, 'male' %>男性 <%= form.radio_button :gender, 'female' %>女性</div><div class="field"> <%= form.label :age %> <%= form.radio_button :age, '20代' %>20代 <%= form.radio_button :age, '30代' %>30代</div>
出力を考える
- 学生ごとの show ページで表示したいもの
- 生徒のデータ(name, mail, gender, age, opinion)
- 生徒の教科ごとの試験結果点数
- 性と全体の試験結果の平均点、最大点、最小点
MySQL上の出力
SELECT subjects.name, CAST(AVG(exam_results.score) as unsigned) as avg_score, MAX(exam_results.score) as max_score, MIN(exam_results.score) as min_scoreFROM studentsINNER JOIN exam_results ON students.id = exam_results.student_idINNER JOIN subjects ON exam_results.subject_id = subjects.idGROUP BY subjects.id, subjects.name
-- =>-- +--------+--------------+-----------+-------+-------+-- | name | name | name | score | ratio |-- +--------+--------------+-----------+-------+-------+-- | taro-1 | 一次試験 | 数学 | 181 | 91 |-- | taro-1 | 試験1 | 数学 | 61 | 31 |-- | taro-1 | 一次試験 | 国語 | 146 | 73 |-- ...
ページ上の出力
students_controllerのshowアクション編集
def show @students = Student.joins(:subjects) .select('students.name, students.email, students.age, students.gender, students.opinion, subjects.id as subject_id') .select('exam_results.name as exam_result_name, subjects.name as subject_name, exam_results.score') .select('CAST((exam_results.score / subjects.max_score) * 100 as unsigned) as ratio') .where(id: params[:id])
avg_result = Student.joins(:subjects) .select('subjects.id as subject_id') .select('CAST(AVG(exam_results.score) as unsigned) as avg_score') .select('MAX(exam_results.score) as max_score') .select('MIN(exam_results.score) as min_score') .group('subjects.id') .order('subjects.id')
@score_hash = {}
avg_result.each do |avg_res| h = Hash.new h[:avg_score] = avg_res.avg_score h[:max_score] = avg_res.max_score h[:min_score] = avg_res.min_score @score_hash[avg_res.subject_id] = h end end
showページのviewを編集
<table border="1"> <tr> <th>科目名</th> <th>点数</th> <th>平均</th> <th>最高</th> <th>最小</th> </tr> <% @students.each do |student| %> <tr> <td><%= student.subject_name %></td> <td><%= student.score %></td> <td><%= @score_hash[student.subject_id][:avg_score] %></td> <td><%= @score_hash[student.subject_id][:max_score] %></td> <td><%= @score_hash[student.subject_id][:min_score] %></td> </tr> <% end %></table>