ความสัมพันธ์
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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ