LoginSignup
0
0

More than 3 years have passed since last update.

10日目(1):マスターデータ(DBへ情報入力、ページに出力

Last updated at Posted at 2019-03-19

大学生データを扱った、前回の分はこちら

使用環境

ホストOS: Windows10 Home
仮想環境OS: Ubuntu Bento/Bionic
Ruby:2.51
Rails:5.2.2

テーブル同士の関連図

マスターデータ関連.jpg

前回の流れ

  1. rails newからのScaffold
  2. Student, Subject, Club, ExamResult(中間), ClubStudent(中間)テーブルの作成
  3. app/modelsで各テーブルの関連性定義
  4. 主キー側のテーブルへデータ入力

今回の流れ

  1. 中間テーブルにデータ入力
  2. 性別の0 or 1の表記を、male or femaleに変更
  3. Studentのshowページに、生徒ごとの試験結果等、データを出力

実段階

Studentsのshowページの、前回までの状態
マスターデータshowの最初.JPG

生徒データと関連付けするときは

student1 = Student.first
student1.clubs << Club.first
student1.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
  end
end

生徒の試験結果情報
id100までの生徒に、9科目の試験を受けてもらう。
なお、点数は0点から各教科ごとに設定の最大点までのランダム


(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
  end
end

Studentsのindexページの表記を変更

app/models/studetns.rb
enum gender: { male: 0 ,female: 1}
enum age: {"teen": 0, "twenty": 1}
app/views/_form.html.erb
<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_score
FROM
    students
INNER JOIN exam_results
    ON students.id = exam_results.student_id
INNER JOIN subjects
    ON exam_results.subject_id = subjects.id
GROUP BY subjects.id, subjects.name
# 出力結果
+--------+--------------+-----------+-------+-------+
| name   | name         | name      | score | ratio |
+--------+--------------+-----------+-------+-------+
| taro-1 | 一次試験     | 数学      |   181 |    91 |
| taro-1 | 試験1        | 数学      |    61 |    31 |
| taro-1 | 一次試験     | 国語      |   146 |    73 |
| taro-1 | 試験2        | 国語      |   200 |   100 |
| taro-1 | 一次試験     | 英語      |   199 |   100 |
| taro-1 | 試験3        | 英語      |   108 |    54 |
| taro-1 | 一次試験     | 化学      |    99 |    99 |
| taro-1 | 試験4        | 化学      |    42 |    42 |
| taro-1 | 一次試験     | 物理      |    62 |    62 |
| taro-1 | 試験5        | 物理      |    56 |    56 |
| taro-1 | 一次試験     | 生物      |    83 |    83 |
| taro-1 | 試験6        | 生物      |    42 |    42 |
| taro-1 | 一次試験     | 世界史    |    62 |    62 |
| taro-1 | 試験7        | 世界史    |    83 |    83 |
| taro-1 | 一次試験     | 日本史    |    77 |    77 |
| taro-1 | 試験8        | 日本史    |    63 |    63 |
| taro-1 | 一次試験     | 地理      |    81 |    81 |
| taro-1 | 試験9        | 地理      |    15 |    15 |
+--------+--------------+-----------+-------+-------+

ページ上の出力

students_controllerのshowアクション編集

Active Record クエリインターフェイス

app/controllers/studetns_controller.rb
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を編集

app/views/students/show.html.erb
<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>

ページ上の出力結果

studentのshowページ編集後.JPG

毎回、コードを自分で考えるも結局自力で辿り着けず、
今回のアウトプットもだか、上コードは講師が正解として出したもの。
見れば、あ~となるけど、まだ自分でコーディングしきれない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0