Blog background
June 11, 2019|Read • 5 Min

Magento 2: Models, Resource Models, and Collections

Written by
Jayanka Ghosh
Jayanka Ghosh
Magento2-Models-ResourceModels-and-Collections

Listen Full Blog Here

Last Updated: Jul 3, 2026

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

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

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.


Also read


CSS Preprocessors: Use of LESS in Magento

Related Blogs

Loading...

Our Offices Are Here

UAE flag

UAE

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

+971 55 557 8583

Saudi Arabia flag

Saudi Arabia

Level 1, Building 7, Zone A Airport road, Business Gate P.O Box 93597 Riyadh 11683, KSA.

+966 50 809 6356

Oman flag

Oman

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

+968 7694 6200

Singapore flag

Singapore

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

India flag

India

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

+91 888 49 00 505

Indonesia flag

Indonesia

Satrio Tower, Floor 6, Unit C and D, Desa/Kelurahan Kuningan Timur, Kec. Setiabudi, Kota Adm. Jakarta Selatan, Provinsi DKI Jakarta