0Pricing
Ruby Academy · บทเรียน

ความสัมพันธ์

has_many และ belongs_to

ความสัมพันธ์ เป็นบทเรียน Ruby Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Ruby Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Ruby Academy มีบทเรียนทั้งหมด 4 บทเรียน

ความสัมพันธ์คืออะไร

ความสัมพันธ์ ใช้ประกาศความเชื่อมโยงระหว่างโมเดล เพื่อให้ Active Record เข้าถึงแถวที่เกี่ยวข้องให้คุณ แทนการเขียนคำสั่งเอสคิวแอลสำหรับเชื่อมตาราง คุณสามารถเรียกใช้คำสั่งอย่าง user.posts ได้

  • ความสัมพันธ์สะท้อนคีย์ต่างประเทศในฐานข้อมูล
  • ระบบจะสร้างคำสั่งช่วยให้โดยอัตโนมัติ
  • ทำให้โค้ดอ่านได้เหมือนแนวคิดของระบบ

ความสัมพันธ์แบบเป็นของ

belongs_to หมายความว่าโมเดลนี้มีคีย์ต่างประเทศที่ชี้ไปยังอีกโมเดลหนึ่ง Comment ที่เป็นของ Post จะมีคอลัมน์ post_id

class Comment < ApplicationRecord
  belongs_to :post
end

# comment.post returns the parent Post
# Requires a post_id column on comments

ความสัมพันธ์แบบมีหลายรายการ

has_many คืออีกด้านหนึ่งของความสัมพันธ์ โดยระเบียนหนึ่งรายการจะเป็นเจ้าของระเบียนอีกชนิดได้หลายรายการ Post มีระเบียน Comment หลายรายการ คีย์ต่างประเทศจะอยู่ที่ด้านที่มีหลายรายการ

class Post < ApplicationRecord
  has_many :comments
end

# post.comments returns all related comments
# post.comments.create(body: "Nice!")

คีย์ต่างประเทศอยู่ที่ใด

โมเดลที่ใช้ belongs_to จะเป็นผู้เก็บคีย์ต่างประเทศ สำหรับ Post และ Comment ตาราง comments จะมี post_id กำหนดสิ่งนี้ในไมเกรชันด้วย t.references :post หรือ add_reference

create_table :comments do |t|
  t.references :post, foreign_key: true
  t.text :body
  t.timestamps
end

คำสั่งที่สร้างขึ้น

has_many :comments จะมอบชุดข้อมูลพร้อมคำสั่งที่มีประโยชน์ให้คุณ:

  • post.comments สำหรับอ่านข้อมูล
  • post.comments.create(...) สำหรับเพิ่มระเบียนที่เชื่อมโยง
  • post.comments.count สำหรับนับจำนวน
  • post.comment_ids สำหรับดูรหัส
post = Post.find(1)
post.comments.create(body: "First!")
puts post.comments.count

ความสัมพันธ์แบบมีหนึ่งรายการ

has_one ใช้จำลองความเชื่อมโยงแบบหนึ่งต่อหนึ่ง เช่น User ที่มี Profile หนึ่งรายการ คีย์ต่างประเทศยังคงอยู่ในอีกโมเดลหนึ่ง (profiles.user_id)

class User < ApplicationRecord
  has_one :profile
end

class Profile < ApplicationRecord
  belongs_to :user
end

ความสัมพันธ์หลายต่อหลายผ่านโมเดลเชื่อมโยง

สำหรับความสัมพันธ์หลายต่อหลาย ให้ใช้โมเดลเชื่อมโยงและ has_many through Student มีระเบียน Course หลายรายการผ่านแถวของ Enrollment

class Student < ApplicationRecord
  has_many :enrollments
  has_many :courses, through: :enrollments
end

class Enrollment < ApplicationRecord
  belongs_to :student
  belongs_to :course
end

ตัวเลือกการลบรายการที่เกี่ยวข้อง

กำหนดสิ่งที่จะเกิดขึ้นกับรายการย่อยเมื่อรายการหลักถูกลบด้วย dependent:

  • dependent: :destroy จะลบรายการย่อยด้วย
  • dependent: :nullify จะล้างค่าคีย์ต่างประเทศของรายการย่อย
  • dependent: :restrict_with_error จะป้องกันการลบ
class Post < ApplicationRecord
  has_many :comments, dependent: :destroy
end

ปัญหาคำสั่งสืบค้น N+1

การวนซ้ำระเบียนและเรียกใช้ความสัมพันธ์อาจทำให้เกิดคำสั่งสืบค้นหนึ่งรายการต่อหนึ่งระเบียน ซึ่งก็คือปัญหา N+1 ที่น่ากังวล การโหลดโพสต์ 10 รายการแล้วโหลดความคิดเห็นของแต่ละรายการอาจทำให้เกิดคำสืบค้น 11 รายการ แทนที่จะเป็น 2 รายการ

ปัญหานี้จะทำให้แอปพลิเคชันช้าลงอย่างเงียบ ๆ เมื่อข้อมูลเพิ่มขึ้น

# N+1: one query per post for comments
Post.all.each do |post|
  puts post.comments.count
end

แก้ปัญหา N+1 ด้วย includes

includes จะบอกให้ Active Record โหลดความสัมพันธ์ล่วงหน้าด้วยคำสืบค้นเพียงไม่กี่รายการ แทนที่จะเป็นจำนวนมาก วิธีนี้เป็นแนวทางมาตรฐานในการแก้ปัญหา N+1

Post.includes(:comments).each do |post|
  puts post.comments.count
end

กำหนดชื่อเองด้วยชื่อคลาส

เมื่อชื่อความสัมพันธ์ไม่ตรงกับโมเดล ให้ใช้ตัวเลือกอย่าง class_name และ foreign_key ตัวอย่างเช่น ความสัมพันธ์ชื่อ author ที่มีโมเดลเบื้องหลังเป็น User

class Post < ApplicationRecord
  belongs_to :author, class_name: "User"
end

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจเกี่ยวกับความสัมพันธ์

ทบทวน: ความสัมพันธ์

คุณได้เรียนรู้วิธีเชื่อมโยงโมเดลแล้ว:

  • belongs_to เก็บคีย์ต่างประเทศ ส่วน has_many และ has_one คืออีกด้านหนึ่งของความสัมพันธ์
  • has_many through ใช้จำลองความสัมพันธ์หลายต่อหลาย
  • dependent ควบคุมการลบรายการที่เกี่ยวข้องต่อเนื่องกัน
  • หลีกเลี่ยงคำสืบค้น N+1 ด้วย includes

ถัดไป เราจะรักษาความถูกต้องของข้อมูลด้วยการตรวจสอบความถูกต้อง และเรียนรู้การสืบค้นข้อมูล

คำถามที่พบบ่อย

บทเรียน “ความสัมพันธ์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ความสัมพันธ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Ruby Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Ruby Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ความสัมพันธ์”

has_many และ belongs_to คุณปฏิบัติ Ruby Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Ruby Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Ruby Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “ความสัมพันธ์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Ruby Academy นี้ได้ไหม

ได้ บทเรียน Ruby Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐาน Active Record
  2. การย้ายโครงสร้างฐานข้อมูล
  3. ความสัมพันธ์
  4. การตรวจสอบความถูกต้องและคำค้น
← กลับไปที่ Ruby Academy