ทำความเข้าใจเกี่ยวกับ Yii Relations – BELONGS_TO vs HAS_ONE

กำลังเริ่มศึกษาเกี่ยวกับ Yii Framework ก็มีเรื่องให้ต้องงงตั้งแต่ต้นกันเลยทีเดียว ซึ่งอันแรกเลยก็จะเป็นการสร้างความสัมพันธ์ (relations) ระหว่าง Model นี่ล่ะ คือประมาณว่า เมื่อไหร่จะใช้ BELONGS_TO เมื่อไรจะใช้ HAS_ONE นั่นเอง

พอศึกษาเข้าใจแล้วก็เอามาเก็บไว้ซะหน่อย เผื่อลืมจะได้มาทบทวนได้บ้าง ^^ จริงๆ ก็ไปเจอ Tutorial นี้มา ก็ต้องขอขอบคุณที่ให้ความกระจ่างนะครับ เวิ่นเว้อนานแล้ว ลุยๆ ก็ยก table ตัวอย่างมา 3 table นะครับ (User, Post, Profile)

USER table
 - id
 - name

POST table
 - id
 - user_id REFERENCES User.id
 - content

PROFILE table
 - id
 - user_id REFERENCES User.id
 - profile_info

มาดูกันว่าอะไรควรจะใช้เมื่อไหร่

BELONGS_TO: ใช้ใน Model ที่มี Foreign Key อ้างไปที่ Primary Key ของ Model อื่น

HAS_ONE: ใช้ใน Model ที่มี Primary Key แล้วมี Model อื่น ใช้ Foreign Key อ้างมาหา โดยฟีลด์ที่ใช้เป็นฟีลด์ที่เป็น Foreign Key

ดูตัวอย่างดีกว่า จะได้เข้าใจกันมากขึ้น

// Post model relations
1.   'user'    => array(self::BELONGS_TO, 'User',    'user_id'),

// Profile model relations
2.   'user'    => array(self::BELONGS_TO, 'User',    'user_id'),

// User model relations
3.   'posts'   => array(self::HAS_MANY,   'Post',    'user_id'),
4.   'profile' => array(self::HAS_ONE,    'Profile', 'user_id'),

ข้อ 1 และ 2 ใช้ Foreign key (user_id) อ้างไปหา Primary Key (User.id) เลยใช้ BELONGS_TO

ข้อ 3 และ 4 ก็จะคล้ายๆ กัน คือ Model(User) ใช้ฟีลด์ (user_id) ของ Model(Post, Profile) ที่กำลังอ้างถึงมาเป็นตัวเชื่อม ก็เลยต้องใช้ HAS_ONE,HAS_MANY แต่ข้อแตกต่างคือ HAS_MANY จะ return ค่ากลับมาเป็น Array ส่วน HAS_ONE จะ return แค่ 1 ค่า

ข้อสังเกตุคือ

  1. ตอนตั้งค่า relations ไม่ต้องระบุชื่อของ Primary Key เพราะ Yii จะไปหามาเองจาก Schema
  2. BELONGS_TO ฟีลด์ที่ใช้อ้างเป็นของตัวเอง (Model) และชี้ไปที่ Primary Key ของ Model ที่อ้างถึง
  3. HAS_ONE/HAS_MANY ฟีลด์ที่ใช้เป็นของ Model ที่อ้างถึง และชี้มาที่ Primary Key ของ Model ที่กำลังตั้งค่าอยู่
  4. ถ้ามีการใช้ BELONGS_TO ใน relations ของ Model อาจจะสร้าง HAS_MANY ที่ Model ที่ถูกอ้างถึงด้วย

ถ้าอ่านแล้วงงๆ ก็ลองเข้าไปอ่านต้นฉบับเลยก็ได้ครับ ฮ่าๆๆ