อธิบาย Relation ต่างๆใน Active Record ยังไม่ค่อย Get เดียวมาอ่านต่อ

หลังจากดองเรื่องนี้มาหน่อย เห็นคนตั้งกระทู้ถาม เลยพึ่งนึกได้ว่ายังไม่ได้รีวิวเรื่องนี้ ;D วันนี้เลยขอจัดซักหน่อย

ในรูปแบบ Active Record นั้นจะมีการเขียนความสัมพันธ์ เพื่อเชื่อมโยง โมเดล 2 โมเดลเข้าหากัน
โดยรูปแบบโครงสร้าง จะเขียนไว้ใน model ที่ต้องการ ตามนี้

Code: [Select]
'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)
VarName เป็นชื่อ อะไรก็ได้ ตั้งมาเพื่อเวลาเราเอาไปเรียนความสัมพันธ์นี้
RelationType เป็น ชนิดของ ความสัมพันธ์
ClassName เป็นชื่อ class model ที่เราจะไปสัมพันธ์ด้วย
ForeignKey เป็นชื่อ field ที่ใช้เชื่อมโยงหรืออ้างอิง 2 ตารางเข้าด้วยกัน


โดยชนิดของความสัมพันธ์หลักๆจะใช้อยู่ 4 ตัว (ถ้า Yii เวอร์ชั่นใหม่ไม่ได้ออกอะไรเพิ่มนะ) ก็คือ

BELONGS_TO = เป็นของ..
HAS_MANY = มีหลายอัน (1 to many)
HAS_ONE = มีแค่หนึ่ง (1 to 1)
MANY_MANY = 1อัน มีหลายอย่าง แต่ละอย่างอาจเป็นของหลายอัน (many to many)


อธิบายอย่างนี้ อาจ งง เลยมาขยายความกันดีกว่า

ตัวอย่างที่จะยกมาอธิบาย ผมจะใช้ ER ตัวอย่างจากเว็บ Yii เลยนะครับ



อธิบาย ER ข้างบน มีอยู่ 5 ตาราง แต่ตารางหลักจริงๆ มี 4 ตาราง (ต้องใช้ Gii สร้าง model ของแต่ละตารางด้วยนะครับ) คือ

tbl_user = เก็บข้อมูลผู้ใช้ -> สร้างโมเดล ชื่อ User
tbl_profile = เก็บรายละเอียด profile ของแต่ละคน -> สร้างโมเดล ชื่อ Profile
tbl_post = เก็บข้อมูลการโพส -> สร้างโมเดล ชื่อ Post
tbl_category = เก็บหมวดหมู่ของโพสนั้น -> สร้างโมเดล ชื่อ Category

ส่วน tbl_post_category เป็นตารางที่เอาไว้เชื่อมความสัมพันธ์แบบ many to many เท่านั้นครับ -> ไม่ต้องสร้างโมเดล

-------------------------------------------------------------------

HAS_ONE

ดูจาด ER แล้วจะเห็นได้ว่า 1 user จะมีแค่ 1 profile เท่านั้น ดังนั้น ความสัมพันธ์จะเป็น 1 to 1 เราจะใช้ HAS_ONE

ความสัมพันธ์ ผมเขียนในโมเดล ของ User
Code: [Select]
class User extends CActiveRecord
{
    ......

    public function relations()
    {
        return array(
            'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'),
        );
    }
}
เมื่อเราเขียนอยู่ในโมเดล ของ User จะเป็นการอ้างว่า โมเดล User นี้จะไปสัมพันธ์กับ โมเดล Profile แบบ HAS_ONE โดยจะใช้ owner_id ของ Profile เป็นตัวอ้างอิง

เวลาเรียกใช้งาน ก็

Code: [Select]
$user=User::model()->findByPk(1); // เรียก user ที่มี id = 1
$profile=$user->profile;
echo $profile->website; // หรือ $user->profile->website; ก็ได้

เป็นต้น

-------------------------------------------------------------------

HAS_MANY

1 user จะสามารถโพสได้หลายโพส ดังนั้น ความสัมพันธ์จะเป็น 1 to many เราจะใช้ HAS_MANY

ความสัมพันธ์ ผมเขียนในโมเดล ของ User
Code: [Select]
class User extends CActiveRecord
{
    ......

    public function relations()
    {
        return array(
            'posts'=>array(self::HAS_MANY, 'Post', 'author_id'),
        );
    }
}
เมื่อเราเขียนอยู่ในโมเดล ของ User จะเป็นการอ้างว่า โมเดล User นี้จะไปสัมพันธ์กับ โมเดล Post แบบ HAS_MANY โดยจะใช้ author_id ของ Post เป็นตัวอ้างอิง

เวลาเรียกใช้งาน

Code: [Select]
$user=User::model()->findByPk(1);
$posts=$user->posts;
foreach($posts as $item){
   echo $item->title;
}
ข้อสังเกตุ $posts ที่ได้นั้นจะมีอยู่หลายค่า(หลายโพส) ดังนั้น จึงต้องใช้ foreach() เข้ามาช่วย

-------------------------------------------------------------------

BELONGS_TO

ในกรณีมองกลับ 1 post จะเป็นของ 1 user เท่านั้น ดังนั้น ความสัมพันธ์เมื่อมองสวนทางกลับ เราจะใช้ BELONGS_TO

ความสัมพันธ์ เขียนในโมเดล ของ Post
Code: [Select]
class Post extends CActiveRecord
{
    ......

    public function relations()
    {
        return array(
            'user'=>array(self::BELONGS_TO, 'User', 'author_id'),
        );
    }
}
เมื่อเราเขียนอยู่ในโมเดล ของ Post จะเป็นการอ้างว่า โมเดล Post นี้จะไปสัมพันธ์กับ โมเดล User แบบ BELONGS_TO โดยจะใช้ author_id ของ Post เป็นตัวอ้างอิง

เวลาเรียกใช้งาน

Code: [Select]
$post=Post::model()->findByPk(10); // โพส id ที่ 10
$user=$post->user;
echo $user->username;

-------------------------------------------------------------------

MANY_MANY

1 post จะมีได้หลาย category และในแต่ละ 1 category อาจจะมีได้หลาย post ก็ได้ จึงเป็นความสัมพันธ์แบบ many to many เราจะใช้ MANY_MANY
ความสัมพันธ์ แบบ many to many นั้นจำเป็นต้องเพิ่มตาราง เพื่อใช้ในการเชื่อมโยง อ้างอิงของ 2 ตารางด้วย นั้นก็คือ ตาราง tbl_post_category นั้นเอง

ความสัมพันธ์ เขียนในโมเดล ของ Post
Code: [Select]
class Post extends CActiveRecord
{
    ......

    public function relations()
    {
        return array(
            'categories'=>array(self::MANY_MANY, 'Category','tbl_post_category(post_id, category_id)'),
        );
    }
}
เมื่อเราเขียนอยู่ในโมเดล ของ Post จะเป็นการอ้างว่า โมเดล Post นี้จะไปสัมพันธ์กับ โมเดล Category แบบ MANY_MANY โดยจะใช้ตาราง tbl_post_category เป็นตารางอ้างอิง มี post_id อ้างอิง id ของโมเดล Post และ category_id อ้างอิง id ของโมเดล Category

เวลาเรียกใช้งาน

Code: [Select]
$post=Post::model()->findByPk(10); // โพส id ที่ 10
$categories=$post->categories;
foreach($categories as $item){
   echo $item->name;
}

-------------------------------------------------------------------

ที่มา http://www.yii.in.th/forum/index.php?topic=420.0

ไม่มีความคิดเห็น:

ขับเคลื่อนโดย Blogger.