今回の授業は、やたらエラーや勘違いに悩まされた。
- rails newで動かない不具合
- stop springで解消
- ruby側で整数型をintと書き間違えることによるエラー
- rubyの整数型はinteger , mysqlはint (C++経験上、intの方が馴染み深い
- rails db:migrateコマでのエラー
- 中間テーブルを先に作ってしまった為。
- 中間テーブルは主テーブルのid等参照するので、作成は一番後。
- 最適なデータ型を選択できなかった
不具合改善の中で、Vagrantfileで、使用できるRAMのサイズを8GBに変更
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)
#準備
##rails new
rails new self_univ -d mysql
gem 'mini_racer', platforms: :ruby
bundle install
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
日本語版があった。
要参照: Active Record の関連付け
class Student < ApplicationRecord
has_many :exam_results
has_many :subjects, through: :exam_results
has_many :club_students
has_many :clubs, through: :club_students
end
class Subject < ApplicationRecord
has_many :exam_results
has_many :students, through: :exam_results
end
class ExamResult < ApplicationRecord
belongs_to :student
belongs_to :subject
end
主キー側の設定の結果、中間テーブル側の設定が自動で変更されていた
class Club < ApplicationRecord
has_many :club_students
has_many :students, through: :club_students
end
class ClubStudent < ApplicationRecord
belongs_to :student
belongs_to :club
end
#マスターデータ作成
studentテーブルへ
(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テーブルへ
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テーブルへ
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側から。
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());
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からでも見れる。はず
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 |
+----+------------+------------+--------------+-------+---------------------+---------------------+