Magento2: Model
Satish Kumar

What is a model?

In Magento, the models are an inherent part of the MVC (Model-View-Controller) architecture. The models are used to do data operations, namely Create, Read, Update and Delete, on a database. The models have many different functions such as manage data, install or upgrade module.

There are three parts of model system in Magento:

  1. Models
  2. Resource Models
  3. Collections

In Magento, ORM is shown as Models (MVC Patterns). Those models are inherited from the Varien_Object class, along with using PHP magic _get and _set functions to set and retrieve the data of the object:

First will create a simple like customer price module and then create a table called “my_customerprice” containing the columns "customerprice_id", "manufacturer", and "model". Let’s we start go through each of the above model system in details:

1. Models

The models are like a black box which provides a layer of abstraction on top of the resource models.The models are data and behavior, representing entities. Anything represented by a database table is most likely going to be a model. The model are fetching, extraction, and manipulation of data occur through models.

Models is also encapsulate the storage independent business logic, we don't know about the database engines or instances, in Magento 2 Data Models are Data Transfer Objects (DTOs), these data implement of the DTO (data model) specific interfaces for Magento CRUD models (the model) determines which class methods are available via the Magento WebAPI.

As per a rule of thumb, every entity we create should have its own model class. Every model extends the MagentoFrameworkModelAbstractModelclass, which inherits the MagentoFrameworkDataObjectclass, hence, we can call the setData and getData functions on our model, to get or set the data of a model respectively.

app/code/Symphisys/CustomerPrice/Model/Price.php

  <?php
    namespace Symphisys\CustomerPrice\Model;   
    use Magento\Framework\Model\AbstractModel;
    use Symphisys\CustomerPrice\Model\ResourceModel\Price as ResourceModel;
    class Price extends AbstractModel
    {
      protected function _construct()
      {
      $this->_init(ResourceModel::class);
      }
    }
 

The Price class only has one method, _construct(), when we call the _init()method, and pass the resource model’s name as its parameter.

2. Resource Models

The connection established to the database is implemented through the resource model. The Resource Models are the data mappers for the storage structure. We are used for making transactions to the database.

All database operations are executed by the resource model and every models must have a resource model, since all of the methods of a resource model expects a model as its first parameter. All resource models must extend the

\Magento\Framework\Model\ResourceModel\Db\AbstractDb

app/code/Symphisys/CustomerPrice/Model/ResourceModel/Price.php

  <?php
    namespace Symphisys\CustomerPrice\Model\ResourceModel;     
    use Magento\Framework\Model\ResourceModel\Db\AbstractDb;    
    class Price extends AbstractDb
    {
      protected function _construct()
      {
        $this->_init('my_customerprice', 'customerprice_id');
      }
    }
  

As we can see, the <Priceclass> here also has one method, <__construct> , where we call the <_initmethod>, and pass two parameters to it. The name of the table in the database, and the name of the primary column in that table.

3. Collections

Let's create the collection now. A collection, i.e you have the ability to search multiple objects in the database. Basically if we create a collection of objects then we add filters that will let we load only certain objects from ours table. The collections are used when we want to fetch multiple rows from our table. Its means collections are a group of models. Collections can be used when we want to

  • Fetch multiple rows from a table
  • Join tables with our primary table
  • Select specific columns
  • Apply a WHERE clause to our query
  • Using GROUP BY or ORDER BY in our query

Collections are encapsulating sets of models and related functionality, such as filtering, sorting, and paging. A collection in Magento is a class that implements both the IteratorAggregate and the Countable PHP5 SPL interfaces. Collections are widely used in Magento to store a set of objects of a specific type. All collections must inherit the

\Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection.

app/code/Symphisys/CustomerPrice/Model/ResourceModel/Price/Collection.php

    <?php
      namespace Symphisys\CustomerPrice\Model\ResourceModel\Price;       
      use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
      use Symphisys\CustomerPrice\Model\Price as Model;
      use Symphisys\CustomerPrice\Model\ResourceModel\Price as ResourceModel;
      class Collection extends AbstractCollection
      {
        protected function _construct()
        {
          $this->_init(Model::class, ResourceModel::class);
        }
      }

In above, our collection class has one method, the <_construct>, where we call the <_init>method and pass two arguments, the name of the model class, and the resource model class.

Using Our Model :

Now, our Model, ResourceModel, and Collection classes are ready, let’s use them in our module:

app/code/Symphisys/CustomerPrice/Block/CustomerPrice.php

    <?php
     namespace Symphisys\CustomerPrice\Block;        
     use Magento\Framework\View\Element\Template;
     use Symphisys\CustomerPrice\Model\ResourceModel\Car\Collection;    
     class CustomerPrice extends Template
     {
      /**
      * @var Collection
      */
      private $collection;
      /**
      * CustomerPrice constructor.
      * @param Template\Context $context
      * @param Collection $collection
      * @param array $data
      */
      public function __construct(
      Template\Context $context,
      Collection $collection,
      array $data = []
      )
      {
        parent::__construct($context, $data);
        $this->collection = $collection;
      }
      public function getAllPrices() {
        return $this->collection;
      }
      public function getAddPricePostUrl() {
        return $this->getUrl('customerprice/price/add');
      }
     }

app/code/Symphisys/CustomerPrice/view/frontend/templates/customerprice.phtml

    <?php
    $prices = $block->getAllPrices();
    ?> 
    <form method="post" action="<?= $block->getAddPricePostUrl() ?>">
      <fieldset>
        <div>
          <label for="manufacturer"><?= __("Customer Name") ?>
          <input type="text" name=" customername " id="customername" />
        </div>
        <div>
          <label for="model"><?= __("Product Name") ?>
          <input type="text" name="productname" id="productname" />
        </div>
        <input type="submit" value="<?= __("Add Price") ?>" />
      </fieldset>
    </form>
    <hr />
    <?php if (count($prices) > 0): ?>
      <table border="1">
        <tr>
          <th><?= __("ID") ?></th>
          <th><?= __(" Customer Name ") ?>
           <?= __(" Product Name ") ?></th>
        </tr>
        <?php foreach ($prices as $price): ?>
        <tr>
          <td><?= $price->getId() ?>
          <td><?= $price->getCustomerName() ?>
          <td><?= $price->getProductName() ?>
        </tr>
      <?php endforeach; ?>
      </table>
    <?php else: ?>
       <h1><?= __("You have no prices yet :(") ?>
    <?php endif; ?>

Now finally we have to make a controller to save the price:

app/code/Symphisys/CustomerPrice /Controller/Price/Add.php

    <?php
    namespace Symphisys\CustomerPrice\Controller\Price;
    use Magento\Framework\App\Action\Action;
    use Magento\Framework\App\Action\Context;
    use Magento\Framework\App\ResponseInterface;
    use Symphisys\CustomerPrice\Model\Price;
    use Symphisys\CustomerPrice\Model\ResourceModel\Price as PriceResource;
    class Add extends Action
    {
        /**
        * @var Price
        */
        private $price;
        /**
        * @var PriceResource
        */
        private $priceResource;
        /**
        * Add constructor.
        * @param Context $context
        * @param Price $price
        * @param PriceResource $priceResource
        */
        public function __construct(
            Context $context,
            Price $price,
            PriceResource $priceResource
        )
        {
            parent::__construct($context);
            $this->price = $price;
            $this->priceResource = $priceResource;
        }     
        public function execute()
        {
            /* Get the post data */
            $data = $this->getRequest()->getParams();
            /* Set the data in the model */
            $priceModel = $this->price;
            $priceModel->setData($data);
            try {
                /* Use the resource model to save the model in the DB */
                $this->priceResource->save($priceModel);
                $this->messageManager->addSuccessMessage("Price saved successfully!");
            } catch (\Exception $exception) {
                $this->messageManager->addErrorMessage(__("Error saving price"));
            }
            /* Redirect back to customer price page */
            $redirect = $this->resultRedirectFactory->create();
            $redirect->setPath('customeprice');
            return $redirect;
        }
    }

Now, when we open our favorite browser, and hit the URL like as follow: <your website url>/ customerprice/ we should be able to see our customer price list.

Share
Tags
Categories

Satish Kumar
Project Lead
Symphisys
Feb 28, 2020