Follow the below steps to create CRUD Model in Magento 2
Step 1: Setup Script
Step 2: Create Model
Step 3: Create Resource Model
Step 4: Create Resource Model Collection
Step 5: Factory Object
Step 1: Setup Script
Firstly, we will create database table for our CRUD models. To do this we need to insert the setup file:
File : app/code/PHPCodez/First/Setup/InstallSchema.php
<?php namespace PHPCodez\First\Setup; use Magento\Framework\Setup\UpgradeSchemaInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\Setup\ModuleContextInterface; class UpgradeSchema implements UpgradeSchemaInterface { public function upgrade( SchemaSetupInterface $setup, ModuleContextInterface $context ) { $installer = $setup; $installer->startSetup(); if(version_compare($context->getVersion(), '0.0.2', '<')) { if (!$installer->tableExists('phpcodez_post')) { $table = $installer->getConnection()->newTable( $installer->getTable('phpcodez_post') ) ->addColumn( 'post_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, [ 'identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true, ], 'Post ID' ) ->addColumn( 'name', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 255, ['nullable => false'], 'Post Name' ) ->addColumn( 'created_at', \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, null, ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT], 'Created At' ) ->setComment('Post Table'); $installer->getConnection()->createTable($table); $installer->getConnection()->addIndex( $installer->getTable('phpcodez_post'), $setup->getIdxName( $installer->getTable('phpcodez_post'), ['name'], \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT ), ['name'], \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT ); } } $installer->endSetup(); } }
File : app/code/PHPCodez/First/Setup/InstallData.php
<?php namespace PHPCodez\First\Setup; use Magento\Framework\Setup\UpgradeDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; class UpgradeData implements UpgradeDataInterface { public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); if (version_compare($context->getVersion(), '0.0.3', '<=')) { $setup->getConnection()->query("INSERT INTO phpcodez_post SET name = 'Post 1'"); } $setup->endSetup(); } }
InstallSchema and InstallData wil be executed when module is getting installed for the first time. If the module is already installed, we can add table scheme and insert data with the help of UpgradeSchema.php and UpgradeData.php.
And to execute this file, you need to upgrade the version number in etc/module.xml file and then issue the below commands
php bin/magento setup:upgrade php bin/magento setup:static-content:deploy php bin/magento cache:flush
Step 2: Create Model
File : app/code/PHPCodez/First/Model/Post.php
<?php namespace PHPCodez\First\Model; class Post extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\DataObject\IdentityInterface { const CACHE_TAG = 'phpcodez_post'; protected $_cacheTag = 'phpcodez_post'; protected $_eventPrefix = 'phpcodez_post'; protected function _construct() { $this->_init('PHPCodez\First\Model\ResourceModel\Post'); } public function getIdentities() { return [self::CACHE_TAG . '_' . $this->getId()]; } public function getDefaultValues() { $values = []; return $values; } }
This model class will extends AbstractModel class 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 the model. You must only use this interface if your model required cache refresh after database operation and render information to the frontend page.
The _construct() method will be called whenever a model is instantiated. Every CRUD model have to use the _construct() method to call _init() method. This _init() method will define the resource model which will actually fetch the information from the database. As above, we define the resource model Mageplaza\Post\Model\ResourceModel\Post The last thing about model is some variable which you should you in your model:
$_eventPrefix – a prefix for events to be triggered
$_eventObject – a object name when access in event
$_cacheTag – a unique identifier for use within caching
Step 3: Create Resource Model
File : app/code/PHPCodez/First/Model/ResourceModel/Post.php <?php namespace PHPCodez\First\Model\ResourceModel; class Post extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context ) { parent::__construct($context); } protected function _construct() { $this->_init('phpcodez_post', 'post_id'); } }
Every CRUD resource model in Magento must extends abstract class \Magento\Framework\Model\ResourceModel\Db\AbstractDb which contain the functions for fetching information from database.
Like model class, this resource model class will have required method _construct(). This method will call _init() function to define the table name and primary key for that table. In this example, we have table mageplaza_helloworld_post and the primary key post_id.
Step 4: Create Resource Model Collection – Get Model Collection
<?php namespace PHPCodez\First\Model\ResourceModel\Post; class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection { protected $_idFieldName = 'post_id'; protected $_eventPrefix = 'phpcodez_post'; protected $_eventObject = 'post_collection'; /** * Define resource model * * @return void */ protected function _construct() { $this->_init('PHPCodez\First\Model\Post', 'PHPCodez\First\Model\ResourceModel\Post'); } }
File : app/code/PHPCodez/First/Model/ResourceModel/Post/Collection.php
Step 5: Factory Object
The Factory class name is the name of Model class and append with the ‘Factory’ word. So for our example, we will have PostFactory class. You must not create this class. Magento will create it for you. Whenever Magento’s object manager encounters a class name that ends in the word ‘Factory’, it will automatically generate the Factory class in the generated/ folder if the class does not already exist. You will see the factory class in generated\code\PHPCodez\First\Model\PostFactory.php
To instantiate a model object we will use automatic constructor dependency injection to inject a factory object, then use factory object to instantiate the model object.
For example, we will call the model to get data in controller.
File : app/code/PHPCodez/First/Controller/Index/Index.php
<?php namespace PHPCodez\First\Controller\Index; class Index extends \Magento\Framework\App\Action\Action { protected $_pageFactory; protected $_postFactory; public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Framework\View\Result\PageFactory $pageFactory, \PHPCodez\First\Model\PostFactory $postFactory ) { $this->_pageFactory = $pageFactory; $this->_postFactory = $postFactory; return parent::__construct($context); } public function execute() { $post = $this->_postFactory->create(); $collection = $post->getCollection(); foreach($collection as $item){ echo "<pre>"; print_r($item->getData()); echo "</pre>"; } exit(); return $this->_pageFactory->create(); } }