Models là một phần quan trọng trong mô hình MVC. Trong Magento 2 Models sẽ chịu trách nhiệm làm việc với database, và được chia thành ba phần là Model, Resource Model và Collection. Được sử dụng để làm việc với các hoạt động CRUD(create, read, update, delete), bạn không cần phải viết bất kỳ một dòng code SQL nào nữa.
Trước khi đi vào nội dung chính của bài viết, tôi sẽ tạo một bảng có tên helloworld_post nằm trong module ViMagento_HelloWorld với các column như sau:
- post_id: khóa chính và tự động tăng
- name
- status
- content
- created_at
Đầu tiên tạo file ViMagento/HelloWorld/etc/db_schema.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?xml version=“1.0”?>
<!—
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
—>
<schema xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=“urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd”>
<table name=“helloworld_post” resource=“default” engine=“innodb” comment=“Post Table”>
<column xsi:type=“int” name=“post_id” padding=“10” unsigned=“true” nullable=“false” identity=“true” comment=“Post ID”/>
<column xsi:type=“varchar” name=“name” nullable=“false” length=“255” default=“simple” comment=“Post Name”/>
<column xsi:type=“int” name=“status” nullable=“false” padding=“10” comment=“Post Status”/>
<column xsi:type=“text” name=“content” nullable=“false” comment=“Post Content”/>
<column xsi:type=“timestamp” name=“created_at” on_update=“true” nullable=“false” default=“CURRENT_TIMESTAMP” comment=“Created Time”/>
<constraint xsi:type=“primary” referenceId=“PRIMARY”><column name=“post_id”/>
</constraint>
<index referenceId=“POST_HELLOWORLD_ATTRIBUTE_SET_ID” indexType=“btree”>
<column name=“post_id”/>
</index>
</table>
</schema>
|
Sau đó chạy câu lệnh php bin/magento setup:upgrade để tạo bảng
Tạo Model trong Magento 2
Tạo file: ViMagento/HelloWorld/Model/Post.php
1
2
3
4
5
6
7
8
9
10
11
|
<?php
namespace ViMagentoHelloWorldModel;
class Post extends MagentoFrameworkModelAbstractModel
{
protected function _construct()
{
$this->_init(‘ViMagentoHelloWorldModelResourceModelPost’);
}
}
|
Một Model thì sẽ extends class AbstractModel và nó gọi phương thức _init và truyền vào một Resource Model như là một đối số để lấy thông tin từ cơ sở dữ liệu. Model sẽ làm việc với cơ sở dữ liệu thông qua resource model.
Tạo Resource Model trong Magento 2
Tạo file: ViMagento/HelloWorld/Model/ResourceModel/Post.php
1
2
3
4
5
6
7
8
9
10
11
|
<?php
namespace ViMagentoHelloWorldModelResourceModel;
class Post extends MagentoFrameworkModelResourceModelDbAbstractDb
{
protected function _construct()
{
$this->_init(‘helloworld_post’, ‘post_id’);
}
}
|
Resource Model sẽ extends class AbstractDb, gọi phương thức _init và truyền vào hai đối số là tên bảng của bạn và khóa chính của bảng. Model sẽ chứa logic tổng thể làm việc với database, nó không thực thi bất kì câu lệnh truy vấn SQL nào cả mà Resource Model sẽ làm điều đó. Resource Model sẽ làm việc trực tiếp với database CRUD(create, read, update, delete).
Tạo Collection trong Magento 2
Tạo file: ViMagento/HelloWorld/Model/ResourceModel/Post/Collection.php
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php
namespace ViMagentoHelloWorldModelResourceModelPost;
class Collection extends MagentoFrameworkModelResourceModelDbCollectionAbstractCollection
{
protected $_idFieldName = ‘post_id’;
protected function _construct()
{
$this->_init(‘ViMagentoHelloWorldModelPost’, ‘ViMagentoHelloWorldModelResourceModelPost’);
}
}
|
Collection phải extends class AbstractCollection và truyền vào phương thức _init hai đối số là model và resource model chúng ta vừa tạo.
Cách sử dụng Model
Vừa rồi chúng ta đã cùng nhau tạo model, resource model và collection cho bảng helloworld_post. Vậy làm sao để sử dụng chúng nhỉ. Trong PHP hướng đối tượng phương thức Factory sẽ khởi tạo đối tượng thì trong Magento cũng tương tự như vậy. Để sử dụng model chúng ta thêm Factory vào sau tên class. Ví dụ: PostFactory. Bạn không cần phải tạo class PostFactory nhé vì Magento sẽ tự động tạo nó cho bạn và được đặt trong thư mục generated. Trông như Magento đã tạo ra một bản nháp để làm việc ấy.
Để lấy một ví dụ thực tế mình sẽ tạo một controller và show dữ liệu ra ngoài màn hình nhé.
Tạo file: ViMagento/HelloWorld/Controller/Post/Index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?php
namespace ViMagentoHelloWorldControllerPost;
class Index extends MagentoFrameworkAppActionAction
{
protected $postFactory;
public function __construct(
MagentoFrameworkAppActionContext $context,
ViMagentoHelloWorldModelPostFactory $postFactory
)
{
$this->postFactory = $postFactory;
return parent::__construct($context);
}
public function execute()
{
$data = $this->postFactory->create()->getCollection();
foreach ($data as $value) {
echo “<pre>”;
print_r($value->getData());
echo “</pre>”;
}
}
}
|
Đây là dữ liệu trong bảng helloworld_post
Và khi truy cập vào đường dẫn đến controller vừa tạo ta sẽ lấy được dữ liệu có trong bảng helloworld_post. Cũng đơn giản phải không nào. example.com/helloworld/post/index
Kết luận
- Model: Chứa logic tổng thể làm việc với database thông qua resource model
- Resource model: Làm việc trực tiếp với database (CRUD)
- Collection: Có thể get một tập hợp model. được sử dụng khi bạn muốn lấy nhiều dòng dữ liệu. Model chỉ có thể load 1 record thôi nhé.
- Factory: Magento sẽ tự động tạo một class trong generated, các bạn cứ hiểu là Magento sẽ tạo một bản nháp và làm việc với nó. Ví dụ: PostFactory, CollectionFactory…