9日目：大学生データ（マスターデータ

今回の授業は、やたらエラーや勘違いに悩まされた。

- rails newで動かない不具合
    - stop springで解消
- ruby側で整数型をintと書き間違えることによるエラー
    - **rubyの整数型はinteger**  , mysqlはint (C++経験上、intの方が馴染み深い
- rails db:migrateコマでのエラー
    - 中間テーブルを先に作ってしまった為。
    - 中間テーブルは主テーブルのid等参照するので、作成は一番後。
- 最適なデータ型を選択できなかった

不具合改善の中で、Vagrantfileで、使用できるRAMのサイズを8GBに変更

```:vagrantfile
config.vm.provider "virtualbox" do |vb
    vb.memory = "8192"
    end
```

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

##作成データ
- テーブル
    - student (id, name,email, gender, age, opinion, updated_at, created_at)
    - ExamResult (id, student, subject, name, score, updated_at, created_at)
        - 中間テーブル
    - Subject (id, name, max_score, updated_at, created_at)
        - ※教科の意
    - ClubStudent (id, student, club, name, updated_at, created_at)
        - 中間テーブル
    - Club (id, name, updated_at, created_at)

#テーブル同士の関連性
![マスターデータ関連.jpg](https://qiita-image-store.s3.amazonaws.com/0/294402/f879117d-9f4b-5224-6500-3f87f97449e4.jpeg)

    
#準備
##rails new
```
rails new self_univ -d mysql
```
```:Gemfile
gem 'mini_racer', platforms: :ruby
```
```
bundle install
```
```qpp/config/database.yml
password: 
```
```
rails db:create
```
#scaffold(本段階
**scaffoldではcontrollerとmodelが同時に作成される)**
**rubyの整数型はinteger**
**中間テーブルは一番最後に作成**
**中間テーブルのうち、主キーを参照するcolumnをreferenceで指定**
→自動で、bigintに設定される

#rails g scaffoldで作成
```
# Studentテーブル
rails generate scaffold Student name:string email:string gender:integer age:integer opinion:text
# Subjectテーブル
rails generate scaffold Subject name:string max_score:integer
# Clubテーブル
rails generate scaffold Club name:string
# ExamResultテーブル
rails generate scaffold ExamResult student:references subject:references name:string score:integer
# ClubStudentテーブル（中間テーブルなので最後
rails generate scaffold ClubStudent student:references club:references name:string
```
##mysql側に反映
```
rails db:migrate
```
##テーブル同士の関連性を定義
[要参照: Active Record Associations](https://guides.rubyonrails.org/association_basics.html)
日本語版があった。
[要参照: Active Record の関連付け](https://railsguides.jp/association_basics.html#belongs-to%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91)

```app/models/student.rb
class Student < ApplicationRecord
  has_many :exam_results
  has_many :subjects, through: :exam_results
  has_many :club_students
  has_many :clubs, through: :club_students
end
```
```app/models/subject.rb
class Subject < ApplicationRecord
  has_many :exam_results
  has_many :students, through: :exam_results
end
```
```app/models/exam_result.rb
class ExamResult < ApplicationRecord
  belongs_to :student
  belongs_to :subject
end
```
主キー側の設定の結果、中間テーブル側の設定が自動で変更されていた

```app/models/club.rb
class Club < ApplicationRecord
  has_many :club_students
  has_many :students, through: :club_students
end
```
```app/models/club_student.rb
class ClubStudent < ApplicationRecord
  belongs_to :student
  belongs_to :club
end
```

#マスターデータ作成

studentテーブルへ

```:console
(1..100).each do |num|
  if num % 2 == 0
    gen = 0
    ag = 0
    at = 0
  else
    gen = 1
    ag = 1
    at = 1
  end
  op = (0..20).map{('あ'..'わ').to_a[rand(26)]}.join

  user = Student.create(name: "taro-#{num}", email: "val-#{num}@gmail.com", gender: gen, age: ag, opinion: op)
end
```

clubテーブルへ

```:console
Club.create(name: '自転車')
Club.create(name: 'サッカー')
Club.create(name: 'バスケットボール')
Club.create(name: 'バレーボール')
Club.create(name: '空手')
Club.create(name: '水泳')
Club.create(name: '登山')
Club.create(name: '陸上')
Club.create(name: 'バイク')
Club.create(name: '英会話')
Club.create(name: 'カメラ')
Club.create(name: '軽音')
Club.create(name: 'サーフィン')
```
subjectテーブルへ

```:console
Subject.create(name: '数学', max_score: 200);
Subject.create(name: '国語', max_score: 200);
Subject.create(name: '英語', max_score: 200);
Subject.create(name: '化学', max_score: 100);
Subject.create(name: '物理', max_score: 100);
Subject.create(name: '生物', max_score: 100);
Subject.create(name: '世界史', max_score: 100);
Subject.create(name: '日本史', max_score: 100);
Subject.create(name: '地理', max_score: 100);
```
##(0..20).map{('あ'..'わ').to_a[rand(26)]}.join
いろいろ詰まってる

###範囲オブジェクト
文字も使える
###mapメソッド
要素の数だけ繰り返しブロックを実行し、ブロックの戻り値を集めた配列を作成して返す。
collectメソッドの別名です。

```
# 配列の入った変数.map {|変数名| 処理内容 }
numbers = ["68", "65", "6C", "6C", "6F"]
p numbers.map {|item| item.to_i(16) }
[104, 101, 108, 108, 111]
#上では16進数を10進数に変換
```
###to_a(Array)
Arrayオブジェクトを返す
###rand(max)
max が 0 の場合は 0.0 以上 1.0 未満の実数を、正の整数の場合は 0 以上 max 未満の整数を返す
###join(sep =)
joinメソッドは、配列の各要素を文字列に変換し、引数sepを区切り文字として結合した文字列を返します。
引数を省略すると区切り文字なしで要素を結合した文字列になる

#関連付けがされたか確認
取り敢えず、student idが1番の人に、データを突っ込んでみる.
rails c側で、うまくできなかったので、mysql側から。

```:mysql
INSERT INTO exam_results (student_id,subject_id,name,score,created_at,updated_at) VALUE 
(1,1,'一次試験',181,now(),now()),(1,2,'一次試験',146,now(),now()),(1,3,'一次試験',199,now(),now()),(1,4,'一次試験',99,now(),now()),(1,5,'一次試験',62,now(),now()),
(1,6,'一次試験',83,now(),now()),(1,7,'一次試験',62,now(),now()),(1,8,'一次試験',77,now(),now()),(1,9,'一次試験',81,now(),now());
```

```:console
stu = Student.first
stu.exam_results

# 結果
# 分かりづらいので、4教科目以降省略、および編集
 stu = Student.first
SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  Student Load (0.2ms)  　
=> #<Student id: 1, name: "taro-1", email: "val-1@gmail.com", gender: 1, age: 1, opinion: "すぎこじぅかいけさぎさあえぃざきこぎごえぎ", created_at: "2019-03-16 11:02:23", updated_at: "2019-03-16 11:02:23">

stu.exam_results
  ExamResult Load (0.2ms)  SELECT  `exam_results`.* FROM `exam_results` WHERE `exam_results`.`student_id` = 1 LIMIT 11
=> #<ActiveRecord::Associations::CollectionProxy 
[#<ExamResult id: 1, student_id: 1, subject_id: 1, name: "一次試験", score: 181, created_at: "2019-03-16 14:33:04", updated_at: "2019-03-16 14:33:04">, 
#<ExamResult id: 2, student_id: 1, subject_id: 2, name: "一次試験", score: 146, created_at: "2019-03-16 14:33:04", updated_at: "2019-03-16 14:33:04">, 
#<ExamResult id: 3, student_id: 1, subject_id: 3, name: "一次試験", score: 199, created_at: "2019-03-16 14:33:04", updated_at: "2019-03-16 14:33:04">,
```
結果の中の、``SELECT  `students`.* FROM `students` ORDER BY `students`.`id` ASC LIMIT 1``と
``SELECT` `exam_results`.* FROM `exam_results` WHERE `exam_results`.`student_id` = 1 LIMIT 11``を使えば、MySQLからでも見れる。はず

```:MySQL

SELECT students.* FROM students ORDER BY students.id ASC LIMIT 1;
+----+--------+-----------------+--------+------+-----------------------------------------------------------------+---------------------+---------------------+
| id | name   | email           | gender | age  | opinion                                                         | created_at          | updated_at          |
+----+--------+-----------------+--------+------+-----------------------------------------------------------------+---------------------+---------------------+
|  1 | taro-1 | val-1@gmail.com |      1 |    1 | すぎこじぅかいけさぎさあえぃざきこぎごえぎ                      | 2019-03-16 11:02:23 | 2019-03-16 11:02:23 |
+----+--------+-----------------+--------+------+-----------------------------------------------------------------+---------------------+---------------------+


SELECT exam_results.* FROM exam_results WHERE exam_results.student_id = 1 LIMIT 11;
+----+------------+------------+--------------+-------+---------------------+---------------------+
| id | student_id | subject_id | name         | score | created_at          | updated_at          |
+----+------------+------------+--------------+-------+---------------------+---------------------+
|  1 |          1 |          1 | 一次試験     |   181 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  2 |          1 |          2 | 一次試験     |   146 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  3 |          1 |          3 | 一次試験     |   199 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  4 |          1 |          4 | 一次試験     |    99 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  5 |          1 |          5 | 一次試験     |    62 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  6 |          1 |          6 | 一次試験     |    83 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  7 |          1 |          7 | 一次試験     |    62 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  8 |          1 |          8 | 一次試験     |    77 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
|  9 |          1 |          9 | 一次試験     |    81 | 2019-03-16 14:33:04 | 2019-03-16 14:33:04 |
+----+------------+------------+--------------+-------+---------------------+---------------------+
```