Blog

Magento 2: Models, Resource Models, and Collections

MAGENTO_2_ Models_Resource_Models_Collections

Table of Contents

Models in Magento are an inherent part of the MVC (Model-View-Controller) architecture something every Adobe Commerce developer works with regularly. Models are used to do data operations, namely Create, Read, Update and Delete, on a database. Magento’s “Model system” is divided into three parts – models, resource models, and collections. In this tutorial, we will be discussing each component individually, and then use all three to make a simple module.

If you wanna follow along, first you’ll have to create a simple hello world module, and then create a table called “my_cars” containing the columns “car_id”, “manufacturer”, and “model”, using an Install Schema setup script.

Model

Models are like a black box which provides a layer of abstraction on top of the resource models. The fetching, extraction, and manipulation of data occur through models. As a rule of thumb, every entity we create (i.e. every table we create in our database) should have its own model class. Every model extends the Magento\Framework\Model\AbstractModelclass, which inherits the \Magento\Framework\DataObjectclass, hence, we can call the setDataand getData functions on our model, to get or set the data of a model respectively. To understand how data objects work, you can read the tutorial on data objects here.

app/code/Jayanka/HelloWorld/Model/Car.php

<?php

namespace Jayanka\HelloWorld\Model;

use Magento\Framework\Model\AbstractModel;
use Jayanka\HelloWorld\Model\ResourceModel\Car as ResourceModel;

class Car extends AbstractModel
{
    protected function _construct()
    {
        $this->_init(ResourceModel::class);
    }
}

The Carclass only has one method, _construct(), when we call the _init()method, and pass the resource model’s name as its parameter. But what is a resource model?

Resource Model

All of the actual database operations are executed by the resource model. Every model 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\AbstractDbclass.

app/code/Jayanka/HelloWorld/Model/ResourceModel/Car.php

<?php

namespace Jayanka\HelloWorld\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class Car extends AbstractDb
{
    protected function _construct()
    {
        $this->_init('my_cars', 'car_id');
    }
}

As we can see, the <Carclass> 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.

Collection

Collections are used when we want to fetch multiple rows from our table. Meaning collections are a group of models. Collections can be used when we want to

app/code/Jayanka/HelloWorld/Model/ResourceModel/Car/Collection.php

<?php
namespace Jayanka\HelloWorld\Model\ResourceModel\Car;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Jayanka\HelloWorld\Model\Car as Model;
use Jayanka\HelloWorld\Model\ResourceModel\Car as ResourceModel;

class Collection extends AbstractCollection
{
    protected function _construct()
    {
        $this->_init(Model::class, ResourceModel::class);
    }
}

All collections must inherit the <Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection> class. Our collection class also 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 that our Model, ResourceModel, and Collection classes are ready, let’s use them.

app/code/Jayanka/HelloWorld/Block/Hello.php

<?php
/**
 *
 * @package     magento2
 * @author      Jayanka Ghosh
 * @license     https://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
 * @link        http://jayanka.me/
 */

namespace Jayanka\HelloWorld\Block;


use Magento\Framework\View\Element\Template;
use Jayanka\HelloWorld\Model\ResourceModel\Car\Collection;

class Hello extends Template
{
    /**
     * @var Collection
     */
    private $collection;

    /**
     * Hello 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 getAllCars() {
        return $this->collection;
    }

    public function getAddCarPostUrl() {
        return $this->getUrl('helloworld/car/add');
    }

}

and in our template file we add a form to add new cars, and a table, listing all the existing cars in the database

app/code/Jayanka/HelloWorld/view/frontend/templates/hello.phtml

<?php
/* @var Jayanka\HelloWorld\Block\Hello $block */
$cars = $block->getAllCars();
?>

<form method="post" action="<?= $block->getAddCarPostUrl() ?>">
   <fieldset>
       <div>
            <label for="manufacturer"><?= __("Manufacturer") ?></label>
           <input type="text" name="manufacturer" id="manufacturer" />
      </div>
       <div>
            <label for="model"><?= __("Model") ?>
           <input type="text" name="model" id="model" />
       </div>
      <input type="submit" value="<?= __("Add Car") ?>" />
   </fieldset>
</form>
<hr />
<?php if (count($cars) > 0): ?>
 <table border="1">
      <tr>
         <th><?= __("ID") ?></th>
          <th><?= __("Manufacturer") ?>
            <?= __("Model") ?></th>
        </tr>
       <?php foreach ($cars as $car): ?>
            <tr>
               <td><?= $car->getId() ?>
               <td><?= $car->getManufacturer() ?>
              <td><?= $car->getModel() ?>
           </tr>
      <?php endforeach; ?>
    </table>
<?php else: ?>
    <h1><?= __("You have no cars yet :(") ?></h1>
<?php endif; ?>

Now finally we have to make a controller to save the car information submitted from the form

app/code/Jayanka/HelloWorld/Controller/Car/Add.php

<?php
/**
 *
 * @package     magento2
 * @author      Codilar Technologies
 * @license     https://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
 * @link        https://www.codilar.com/
 */

namespace Jayanka\HelloWorld\Controller\Car;


use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Jayanka\HelloWorld\Model\Car;
use Jayanka\HelloWorld\Model\ResourceModel\Car as CarResource;

class Add extends Action
{
    /**
     * @var Car
     */
    private $car;
    /**
     * @var CarResource
     */
    private $carResource;

    /**
     * Add constructor.
     * @param Context $context
     * @param Car $car
     * @param CarResource $carResource
     */
    public function __construct(
        Context $context,
        Car $car,
        CarResource $carResource
    )
    {
        parent::__construct($context);
        $this->car = $car;
        $this->carResource = $carResource;
    }

    /**
     * Execute action based on request and return result
     *
     * Note: Request will be added as operation argument in future
     *
     * @return \Magento\Framework\Controller\ResultInterface|ResponseInterface
     * @throws \Magento\Framework\Exception\NotFoundException
     */
    public function execute()
    {
        /* Get the post data */
        $data = $this->getRequest()->getParams();

        /* Set the data in the model */
        $carModel = $this->car;
        $carModel->setData($data);

        try {
            /* Use the resource model to save the model in the DB */
            $this->carResource->save($carModel);
            $this->messageManager->addSuccessMessage("Car saved successfully!");
        } catch (\Exception $exception) {
            $this->messageManager->addErrorMessage(__("Error saving car"));
        }

        /* Redirect back to cars page */
        $redirect = $this->resultRedirectFactory->create();
        $redirect->setPath('helloworld');
        return $redirect;
    }
}

Now, when we open our favourite browser, and hit the URL http://mywebsite.com/helloworld/, we should be able to see our car list.

That’s all there is to know about the basics of models in Magento. If you want us to make a tutorial blog post about a particular topic comment below.

Picture of Jayanka Ghosh

Jayanka Ghosh

Experienced Magento Developer with a proven track record in the IT and services industry, specializing in PHP, Magento, HTML, jQuery, CSS, and E-commerce.

You May Also Like

Latest Blogs

Magento Development Company

Let’s talk

Our Offices

DTECH, Techno Hub 1, Dubai Silicon Oasis Authority, United Arab Emirates – Dubai – United Arab Emirates

Singapore

Codilar Digital Pte Ltd, 68 Circular Road, #02-01, 049422, Singapore

India

Bengaluru

7th Floor, Jupiter Block ,Prestige Tech Park, Kadubeesanahalli, Bellandur Amanikere, Bengaluru, Karnataka 560103

Calicut

SBC No 4 & 6 upper basement, Sahya Building
KSITIL SEZ, Cyberpark Kozhikode Park Rd, Nellikkode, Kozhikode, Kerala 673016

Kolkata

Astra Towers, ANO -523 ,North Block, Action Area IIC, Newtown, Kolkata, West Bengal 700135

Ahmedabad

Codilar Technologies, Connekt, 13th Floor, Gala Empire, Opposite T.V. Tower, Drive In Rd, Memnagar, Ahmedabad, Gujarat – 380052

Oman

Building No. 2/796, Way No. 43, Block No. 336, Al Khud 132, Muscat, Oman

Codilar

© Copyright Codilar 2025. All Rights Reserved. Privacy Policy

Send Feedback

Request PWA Demo