มาทำ Has one, Has many ใน Ruby on Rails กัน
ต่อเนื่องจาก CRUD
วันนี้ผมจะสร้างตาราง genders เพื่อเก็บเพศ แล้วนำไปเชื่อมความสัมพันธ์กับตาราง students
Has one
โดยให้เราสร้าง Model และไฟล์ Migration สำหรับสร้างตาราง genders หรือง่ายๆเลยก็ใช้คำสั่งนี้ จะได้ทั้งคู่
rails g model gender


จะได้แบบนี้
หลังจากนี้ให้เพิ่ม column ที่ต้องการลงไป
ต่อไปเราก็จะเพิ่ม reference ให้ตาราง students โดยใช้คำสั่งสร้างไฟล์ Migration
rails g migration add_reference_gender_to_students

และเพิ่ม code ดังนี้ได้เลยครับ
หลังจากนั้นให้รันคำสั่ง
rails db:migrate

โอเคผ่านครับ
ลองเช็คใน schema.rb หน่อยว่ามี gender_id ในตาราง students หรือยัง

ต่อไปเราจะเชื่อมความสัมพันธ์กันใน Model กันต่อให้เพิ่ม code ให้เป็นดังนี้
Model student นะครับ
Model gender นะครับ
ต่อไปเราจะเขียน seed ไฟล์ เพื่อให้มี gender ไว้เรียกใช้ โดยให้ไปที่ไฟล์ db/seeds.rb และเพิ่ม code ดังนี้
และให้รันคำสั่ง
rails db:seed

ก่อนรัน ไม่มีข้อมูลในตาราง

หลังรันคำสั่ง rails db:seed

ต่อไปเราจะไปที่ controller เพื่อเพิ่ม params gender_id ใน student_params
จากนั้นมาลอง ให้เราไปที่ Model student เพื่อเพิ่มให้ return genders.name แทน gender_id
จากนั้นไปปรับ code ใน controller ให้ return แบบ as_json({ api: true })
มาลองกันหน่อย โดยใช้ Postman ยิงมาสร้าง นักเรียน พร้อม gender_id = 1

ถ้าไม่อยากได้ column ไหนให้เพิ่มในเช่น ไม่เอา id, gender_id
super().except('id', 'gender_id')
การเรียกใช้ก็สามารถเรียก student.gender แบบนี้ได้เลย
student = Student.last # .last ก็คือนักเรียนคนสุดท้าย
ap student.gender

จบเรื่อง has_one ใน rails
Has many
has many เราต้องสร้างเพิ่ม อีก 2 ตาราง ก็คือตาราง courses สำหรับเก็บวิชาเรียน และ student_courses เพื่อเก็บว่านักเรียนคนนี้มี เรียนวิชาอะไรบ้าง
งั้นเรามาเริ่มกันเลย โดยการสร้าง Model และ ตาราง courses ด้วยคำสั่ง
rails g model course

และเพิ่ม code ดังนี้
และสร้าง Model และ ตาราง student_courses ด้วยคำสั่ง
rails g model student_course

และเพิ่ม code ดังนี้
จากนั้นรันคำสั่ง
rails db:migrate

มาต่อกันที่ code seed เพื่อเพิ่มวิชาต่างๆ
พร้อมรันคำสั่ง
rails db:seed
Model StudentCourse
Model Course
Model student
มาทำ controller กันและ routes กันต่อ ให้เพิ่ม Action add_course เป็น POST
Routes
มาลองยิง ด้วย Postman กัน http://localhost:3000/students/:id/add_course

ลองยิงแบบ course_id เดิมเพื่อลอง เช็คว่า validate ทำงานถูกต้องไหม

เราสามารถเรียก student.student_courses ได้เลย
student = Student.find_by_id(8)
student.student_courses
ก็จะได้แบบนี้

อันนี้เราจะมาลอง ใช้ .map เพื่อให้ดึง code และ name มาแสดงแทน ให้ปรับ code เป็นตามนี้
ก็จะได้เป็นแบบนี้ครับ

จบแล้วครับ
สำหรับใครอยากดู code ทั้งก็ตาม link นี้เลยครับ