12/08/2018, 15:45

Giới thiệu về Orm Creating models and Relating Models trong Fuel PHP

1. Tạo Models Model có thể tạo một cách nhanh chóng và dễ dàng. Trong Model của Fuel có các convention khác các framework khác, model được đặt tên có tiền tố Model_ cho class đó. Ví dụ như Model_Article class sử dụng tên file article.php. Model được đặt trong thư mục /app/classes/model/ . Tuy ...

1. Tạo Models

Model có thể tạo một cách nhanh chóng và dễ dàng. Trong Model của Fuel có các convention khác các framework khác, model được đặt tên có tiền tố Model_ cho class đó. Ví dụ như Model_Article class sử dụng tên file article.php. Model được đặt trong thư mục /app/classes/model/ . Tuy nhiên bạn có thể sử dụng bất kỳ tên nào bạn muốn đặt mà không cần tuân theo convention.

Ví dụ:

class Model_Article extends OrmModel {}

Ví dụ trên chỉ làm việc với MySQL và MySQLi bởi vì nó cần phải lấy các thuộc tính mô hình từ cơ sở dữ liệu. Tuy nhiên nó không phải là rất hiệu quả và do đó không khuyến khích sử dụng nó theo cách này bởi vì bạn sẽ luôn luôn cần một truy vấn thêm cho mỗi model chỉ để lấy tên cột

Ví du:

class Model_Article extends OrmModel
{
    protected static $_properties = array('id', 'title', 'contents', 'publish');
}

2. Cấu hình Models

Bạn có thể thêm thuộc tính vào Model để cấu hình nó Như mình đã trình bày ở phần 1, việc setting các thuộc tính cho model là không bắt buộc, tuy nhiên khi tạo model mọi người nên setting thuộc tính cho model đó. Khi setting properties, chúng ta có thể khai báo public hay protected, lưu ý là không thể khai báo private. Lưu ý rằng tất cả các thuộc tính cấu hình được đặt trước bằng một dấu gạch dưới đơn để tránh va chạm với các tên cột của bạn.

  • protected static $$table_name

Model với tên Model_Article là model cho table "articles". Nếu bạn ko đặt tên đúng quy chuẩn này thì bạn có thể setting lại bằng cách thêm thuộc tính $$table_name.

Ví dụ:

class Model_Article extends OrmModel
{
    protected static $_table_name = 'myarticles';
}
  • protected static $$primary_key

Theo mặc định điều này được thiết lập từ array('id') . Nếu bạn sử dụng một tên cột khác hoặc nhiều khóa chính bạn cần phải thiết lập thuộc tính này.

Ví dụ:

class Model_Article extends OrmModel
{
    protected static $_primary_key = array('aid');
}

Khóa chính phải là khóa: duy nhất và không thay đổi.

  • protected static $$properties

Đã có một ví dụ đơn giản ở trên để thêm tất cả các thuộc tính cho model, chúng cũng có thể được cấu hình bằng cách sử dụng tên cột như là khoá và các tùy chọn cài đặt như type, label và validation.

Ví dụ:

class Model_Article extends OrmModel
{
    protected static $_properties = array(
        'id', // both validation & typing observers will ignore the PK
        'name' => array(
            'data_type' => 'varchar',
            'label' => 'Article Name',
            'validation' => array('required', 'min_length' => array(3), 'max_length' => array(20)),
            'form' => array('type' => 'text'),
            'default' => 'New article',
        ),
        'gender' => array(
            'data_type' => 'varchar',
            'label' => 'Gender',
            'form' => array('type' => 'select', 'options' => array('m' => 'Male', 'f' => 'Female')),
            'validation' => array('required'),
        ),
        'created_at' => array(
            'data_type' => 'int',
            'label' => 'Created At',
            'form' => array(
                'type' => false, // this prevents this field from being rendered on a form
            ),
        ),
        'updated_at' => array('data_type' => 'int', 'label' => 'Updated At')
    );
}

Các form thuộc tính có thể được truyền theo dạng một mảng như trong ví dụ.

Validation rules có thể được thông qua như là một trong hai quy tắc: array ('required') hoặc như là một rule với một mảng các params: mảng ('min_length' => mảng (3)) cả hai được hiển thị trong ví dụ trên. Giải thích đầy đủ về class Validation và rules của nó có thể được tìm thấy trong phần Core. Bạn cần thiết lập Observer_Validation để chạy xác nhận.

  • protected static $$conditions

Theo mặc định thuộc tính này không tồn tại và Model :: condition () trả về array(). Tuy nhiên bạn cũng có thể thiết lập trong model nếu bạn muốn bất kỳ điều kiện nào được xác định trên mỗi truy vấn được thực hiện.Hiện tại, 'order_by' và 'where' được hỗ trợ.

Ví dụ:

class Model_Article extends OrmModel
{
    protected static $_conditions = array(
        'order_by' => array('id' => 'desc'),
        'where' => array(
            array('publish_date', '>', 1370721177),
            array('published', '=', 1),
        ),
    );
}

Order_by chỉ được áp dụng nếu không xác định được thứ tự khác trong truy vấn. Where được thêm vào bằng cách sử dụng and đối với bất kỳ mệnh đề nào khác được xác định.

  • protected static hasone,_has_one, hasone,_belongs_to, hasmany,_has_many, hasmany,_many_many

The Orm hỗ trợ các loại mối quan hệ sau natively:

  • Belongs To
  • Has One
  • Has Many
  • Many to Many

3. Relating Models

3.1. Relations: Belongs To

Khóa chính (Primary key) trong bảng là thể hiện sự ràng buộc tới một bảng khác: thuộc về 1 đối tượng liên quan. Đây là phía bên kia của mối quan hệ HasOne hoặc HasMany. Ví dụ: Giả sử chúng ta có mô hình Model_Comment và nó thuộc về Model_Post (một post có nhiều comment) như vậy id của Model_Post sẽ được lưu và bảng của Model_Comment. Điều này có nghĩa bảng comments sẽ có cột post_id (hoặc cái tên khác bạn cấu hình). Nếu bạn giữ nguyên mặc định thì tất cả những gì bạn cần làm là thêm 'post' vào static property $$belongs_to của Model_Comment:

Ví dụ:

protected static $_belongs_to = array('post');

Dưới đây là những ví dụ để thiết lập và breaking các mối quan hệ belongs-to:

Ví dụ:

// both main and related object are new:
$comment = new Model_Comment();
$comment->post = new Model_Post();
$comment->save();

// both main and related object already exist
$comment = Model_Comment::find(6);
$comment->post = Model_Post::find(1);
$comment->save();

// break the relationship established above
$comment = Model_Comment::find(6);
$comment->post = null;
$comment->save();

Ví dụ cấu hình đầy đủ với giá trị mặc định là giá trị:

// in a Model_Comment which belong to a post
protected static $_belongs_to = array(
    'post' => array(
        'key_from' => 'post_id',
        'model_to' => 'Model_Post',
        'key_to' => 'id',
        'cascade_save' => true,
        'cascade_delete' => false,
    )
);

3.2. Relations: Has One

Chỉ định quan hệ một-một với model khác. Giả sử chúng ta có model Model_User và nó có một Model_Profile. Điều này có nghĩa là bảng profiles sẽ có một user_id cột (hoặc cái tên khác bạn cấu hình), trong khi bảng user sẽ không đề cập đến trong profile. Nếu bạn giữ nguyên mặc định thì tất cả những gì bạn cần làm là thêm 'profile' vào static property $$_has_one của Model_User:

Ví dụ:

protected static $_has_one = array('profile');

Dưới đây là những ví dụ để thiết lập và breaking các mối quan hệ has_one:

// both main and related object are new:
$user = new Model_User();
$user->profile = new Model_Profile();
$user->save();

// both main and related object already exist
$user = Model_User::find(6);
$user->profile = Model_Profile::find(1);
$user->save();

// break the relationship established above
$user = Model_User::find(6);
$user->profile = null;
$user->save();

Ví dụ cấu hình đầy đủ với giá trị mặc định là giá trị:

// in a Model_User which has one profile
protected static $_has_one = array(
    'profile' => array(
        'key_from' => 'id',
        'model_to' => 'Model_Profile',
        'key_to' => 'user_id',
        'cascade_save' => true,
        'cascade_delete' => false,
    )
);

3.3. Relations: Has Many

Chỉ định quan hệ một-nhiều với model khác. Giả sử chúng ta có model Model_Post và nó có nhiều Model_Comments. ID của Model_Post được lưu Model_Comment instance trong bảng riêng của nó. Điều này có nghĩa bảng comments sẽ có một cột post_id (hoặc cái tên khác bạn cấu hình), trong khi bảng posts sẽ không đề cập đến comments. Nếu bạn giữ nguyên mặc định tất cả những gì bạn cần làm là thêm 'comments' vàostatic property $$_has_many của Model_User:

Ví dụ:

protected static $_has_many = array('comments');

Dưới đây là những ví dụ để thiết lập và breaking các mối quan hệ has_many:

// both main and related object are new:
$post = new Model_Post();
$post->comments[] = new Model_Comment();
$post->save();

// both main and related object already exist
$post = Model_Post::find(1);
$post->comments[6] = Model_Comment::find(6); // assigning it to comments[6] is not required but recommended
$post->save();

// break the relationship established above
$post = Model_Post::find(1);
unset($post->comments[6]);
$post->save();

Ví dụ cấu hình đầy đủ với giá trị mặc định là giá trị:

// in a Model_Post which has many comments
protected static $_has_many = array(
    'comments' => array(
        'key_from' => 'id',
        'model_to' => 'Model_Comment',
        'key_to' => 'post_id',
        'cascade_save' => true,
        'cascade_delete' => false,
    )
);

3.4. Relations: Many to Many

Chỉ định một mối quan hệ nhiều - nhiều với một model khác. Để thiết lậpmối quan hệ này, bạn cần một bảng trung gian chỉ với 2 ID từ cả hai phía của quan hệ là khóa chính kép.

Ví dụ định nghĩa quan hệ thông qua bảng:

protected static $_many_many = array(
    'users' => array(
        'table_through' => 'posts_users', 	// both models plural without prefix in alphabetical order
        'conditions' => array(
           'order_by' => array(
                'posts_users.status' => 'ASC'	// define custom through table ordering
            ),
        ),
    )
);
// other fields that may be required have been ommitted for this example

Giả sử chúng ta có model Model_Post và nó có nhiều và thuộc về nhiều Model_Users. ID của Model_Post cùng với ID của Model_User trong một bảng được gọi là posts_users (thứ tự mặc định theo thứ tự chữ cái). Bảng đó chỉ có 2 cột: post_id và user_id cùng với khoá chính của bảng đó. Nếu bạn giữ nguyên mặc định tất cả những gì bạn cần làm là thêm 'users' vào thuộc tính tĩnh $$_many_many của Model_Post:

Ví dụ:

protected static $_many_many = array('users');

Và bạn cần phải thêm một bảng như thế này để SQL của bạn:

CREATE TABLE IF NOT EXISTS `posts_users` (
  `post_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`post_id`,`user_id`)
);

Dưới đây là những ví dụ để thiết lập và breaking các mối quan hệ many_many:

// both main and related object are new:
$post = new Model_Post();
$post->users[] = new Model_User();
$post->save();

// both main and related object already exist
$user = Model_User::find(8);
$user->posts[1] = Model_Post::find(1);
$user->save();

// break the relationship established above
$post = Model_Post::find(1);
unset($post->users[8]);
$post->save();

Ví dụ cấu hình đầy đủ với giá trị mặc định là giá trị:

// in a Model_Post which has and belongs to many Users
// = multiple posts per user and multiple users (authors) per post
protected static $_many_many = array(
    'users' => array(
        'key_from' => 'id',
        'key_through_from' => 'post_id', // column 1 from the table in between, should match a posts.id
        'table_through' => 'posts_users', // both models plural without prefix in alphabetical order
        'key_through_to' => 'user_id', // column 2 from the table in between, should match a users.id
        'model_to' => 'Model_User',
        'key_to' => 'id',
        'cascade_save' => true,
        'cascade_delete' => false,
    )
);

4. Tổng kết và tài liệu tham khảo

Hi vọng phần giới thiệu trên có thể giúp các bạn hiểu Fuelphp với cách thiết lập các mối quan hệ đơn giản, quản lý các bảng trong cơ sở dữ liệu và các quan hệ giữa chúng, qua đó chúng ta cũng sẽ biết cách để lấy dữ liệu như thế nào cho phù hợp với yêu cầu đặt ra. Thôi thì xong rồi, chúc bà con ngủ ngon (haiz)

  1. https://fuelphp.com/docs/index.html
  2. https://fuelphp.com/docs/packages/orm/relations/belongs_to.html
  3. https://fuelphp.com/docs/packages/orm/relations/has_one.html
  4. https://fuelphp.com/docs/packages/orm/relations/has_many.html
  5. https://fuelphp.com/docs/packages/orm/relations/many_many.html
0