Working with Resource Models in Magento 2

What is A Resource Model?

A resource model is a model that is responsible for the CRUD (Create, Read, Update, Delete) implementations for the Magento ORM.  In simple terms, it is used to process your data from your model to your database.  Models hold your data.  Resource models do something with that data.

Normally, applications will have both of these responsibilities in one class.  Magento enforces a separation of responsibility by breaking up these responsibilities into two separate classes.

Resource models should contain logic only pertaining to CRUD operations.  Nothing else.

Resource Model Basics

Resource models extend the Magento\Framework\Model\ResourceModel\Db\AbstractDb  class.  It must implement the method _construct() .  In this method, you set your associated table (to get and set data from) and your primary key for that table.  You do this in the _init()  method.  See this article for more information.

Hook Methods

There are a number of hook methods available from within your resource models.  It is usually these methods that are overridden when customizing a resource model.

The methods are:

  • _afterLoad()
  • _beforeSave()
  • _afterSave()
  • _beforeDelete()
  • _afterDelete()

How to Use Resource Models

The good news is that you do not have to do much in terms of leveraging resource models.  Once they are created, Magento takes over and does the rest.

You can perform a series of customizations through the use of the hook methods if you want automatic actions to happen.

For example, we can load associated data from another table.

<?php
  
namespace Ecommage\Blog\Model\ResourceModel;
  
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use Magento\Framework\Model\ResourceModel\Db\Context;
  
class Post extends AbstractDb {
  
    protected $taxonomyFactory;
  
    public function __construct(
        Context $context,
        $connectionName,
        \Ecommage\Blog\Model\TaxonomyFactory $taxonomyFactory
    ) {
        $this->taxonomyFactory = $taxonomyFactory;
        parent::__construct( $context, $connectionName );
    }
  
    public function _construct() {
        $this->_init( 'blog_posts', 'post_id' );
    }
  
    protected function _afterLoad( \Magento\Framework\Model\AbstractModel $object ) {
        $taxonomy = $this->taxonomyFactory->create();
        $taxonomy->loadByPostId($object->getId());
        $object->setData('taxonomy', $taxonomy->getData());
        return parent::_afterLoad( $object );
    }
}

In the example above, we automatically fetched associated taxonomy for a blog post with the _afterLoad()  hook method.  The same concept can be done for _afterSave()  and _afterDelete() .

In another example, let’s set the creation time automatically when we save a new entity.

<?php
  
namespace Ecommage\Blog\Model\ResourceModel;
  
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use Magento\Framework\Model\ResourceModel\Db\Context;
use Magento\Framework\Stdlib\DateTime\DateTime;
  
class Post extends AbstractDb {
  
    protected $datetime;
     
    public function __construct(
        Context $context,
        $connectionName,
        DateTime $dateTime
    ) {
        $this->datetime = $dateTime;
        parent::__construct( $context, $connectionName );
    }
  
    public function _construct() {
        $this->_init( 'blog_posts', 'post_id' );
    }
  
    protected function _beforeSave( \Magento\Framework\Model\AbstractModel $object ) {
        if($object->isObjectNew() && !$object->getCreationTime()) {
            $object->setCreationTime($this->datetime->gmtDate());
        }
        return parent::_beforeSave( $object );
    }
}

As you can see, we can automatically set the creation_time of the table without having the user manually do it every time we create a new record in the database.

Resource models do a lot of heavy lifting, but we usually never see it happen.

Remember to always leverage resource models to their fullest!

Comment

There is no comment on this post. Be the first one.

Leave a comment