Magento 2 Development 04 Model, Resource Model, and Collection

0

 

How to perform CRUD operations in Magento 2 – Now that we have created the tables. We need some way to manipulate (i.e. to perform CRUD operations) the table data of the database.

To perform the CRUD (Create, Read, Update, Delete) operations we have to create these three classes (i.e. Model, Resource Model, and Collection) for each table. The name, Model comes from MVC (Model-View-Controller) architecture.

Model

The model represents a single entity. By that, I mean a single row of the table. The model provides a layer of abstraction over the resource model.

Let’s create a model for “blogmanager_blog” table. For that inside our module folder create a folder named Model. Inside that folder create Blog.php file,


<?php
namespace Webkul\BlogManager\Model;
class Blog extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\DataObject\IdentityInterface
{
const NOROUTE_ENTITY_ID = 'no-route';
const ENTITY_ID = 'entity_id';
const CACHE_TAG = 'webkul_blogmanager_blog';
protected $_cacheTag = 'webkul_blogmanager_blog';
protected $_eventPrefix = 'webkul_blogmanager_blog';
public function _construct()
{
$this->_init(\Webkul\BlogManager\Model\ResourceModel\Blog::class);
}
public function load($id, $field = null)
{
if ($id === null) {
return $this->noRoute();
}
return parent::load($id, $field);
}
public function noRoute()
{
return $this->load(self::NOROUTE_ENTITY_ID, $this->getIdFieldName());
}
public function getIdentities()
{
return [self::CACHE_TAG.'_'.$this->getId()];
}
public function getId()
{
return parent::getData(self::ENTITY_ID);
}
public function setId($id)
{
return $this->setData(self::ENTITY_ID, $id);
}
}

The model class will extends \Magento\Framework\Model\AbstractModel and implements \Magento\Framework\DataObject\IdentityInterface. The IdentityInterface will force Model class define the getIdentities() method which will return a unique id for each model.

Earlier I said “The model provides a layer of abstraction over the resource model.” by that I meant that we use the model class in our code to manipulate the tables but the actual query get executed by the resource model class. So every model will require a resource model which will execute the actual sql queries. When we create a new object the _construct method will get executed, which will call the init method where we have to pass the resource model as param.

Similarly we need to create the model for “blogmanager_comment” table as Model/Comment.php ,

<?php
namespace Webkul\BlogManager\Model;
class Comment extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\DataObject\IdentityInterface
{
const NOROUTE_ENTITY_ID = 'no-route';
const ENTITY_ID = 'entity_id';
const CACHE_TAG = 'webkul_blogmanager_comment';
protected $_cacheTag = 'webkul_blogmanager_comment';
protected $_eventPrefix = 'webkul_blogmanager_comment';
public function _construct()
{
$this->_init(\Webkul\BlogManager\Model\ResourceModel\Comment::class);
}
public function load($id, $field = null)
{
if ($id === null) {
return $this->noRoute();
}
return parent::load($id, $field);
}
public function noRoute()
{
return $this->load(self::NOROUTE_ENTITY_ID, $this->getIdFieldName());
}
public function getIdentities()
{
return [self::CACHE_TAG.'_'.$this->getId()];
}
public function getId()
{
return parent::getData(self::ENTITY_ID);
}
public function setId($id)
{
return $this->setData(self::ENTITY_ID, $id);
}
}

Resource Model

We have already discussed about the importance of resource model. So let’s just dive into code.

First we will create the resource model for “blogmanager_blog” table. For that we have to create a ResourceModel folder under the Model folder, and inside that ResourceModel folder we will create Blog.php file.

<?php
namespace Webkul\BlogManager\Model\ResourceModel;
class Blog extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
public function _construct()
{
$this->_init("blogmanager_blog", "entity_id");
}
}

Here we have to mention our table name and the primary key of the table. All the resource model classes will extend \Magento\Framework\Model\ResourceModel\Db\AbstractDb class which have the common functions for actual database operations.

Similarly we need to create the resource model for “blogmanager_comment” table as Model/ResourceModel/Comment.php ,

<?php
namespace Webkul\BlogManager\Model\ResourceModel;
class Comment extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
public function _construct()
{
$this->_init("blogmanager_comment", "entity_id");
}
}

Collection

We know that the model represents a single row of the table whereas the collection represents all the rows of the table. We can think of the collection as collection of models or “Select * From Table table_name”.

So if we have to access all/multiple rows of the table, or perform some filter with where/like, or perform some sorting with order by then we should use collection.

Whereas if we have to insert a single row or fetch a single row or update some column in a row or delete a row then we have to use model.

Now let’s create collection class for “blogmanager_blog” table. For that we have to create a folder with the same name as the resource model class name under the ResourceModel folder. So here we will create a folder named Blog under Model/ResourceModel/ folder. And under that folder we will create Collection.php class.

<?php
namespace Webkul\BlogManager\Model\ResourceModel\Blog;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected $_idFieldName = 'entity_id';
public function _construct()
{
$this->_init(
\Webkul\BlogManager\Model\Blog::class,
\Webkul\BlogManager\Model\ResourceModel\Blog::class
);
$this->_map['fields']['entity_id'] = 'main_table.entity_id';
}
}

Here we have to provide both the model and the resource model when we call the init method in the constructor.

Similarly we can create the collection for “blogmanager_comment” table as Model/ResourceModel/Comment/Collection.php ,

<?php
namespace Webkul\BlogManager\Model\ResourceModel\Comment;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected $_idFieldName = 'entity_id';
public function _construct()
{
$this->_init(
\Webkul\BlogManager\Model\Comment::class,
\Webkul\BlogManager\Model\ResourceModel\Comment::class
);
$this->_map['fields']['entity_id'] = 'main_table.entity_id';
}
}

After creating all of the classes we need to run the di compile command. Which if you remembered was php bin/magento setup:di:compile

The di compile will generate some codes automatically which you can find in generated/code folder under magento root directory. We will learn in more detail about code generation in later part of this blog series.

PS. Please check the namespace of the class if you get confused with the folder structure.

Here we learned why and how to create these classes. In next blogs we will see how to use them.

The folder structure till now should be like,

2021-02-06_17-27

Post a Comment

0Comments
Post a Comment (0)
To Top