Model are used to logical + data operations in MVC pattern. In magento, these are used for the same propose.

In this blog, we will continue on the previous blog created, will make these changes to the config.xml file.

There are two parts to models in magento, 1st is the Model file and 2nd Model resource files. Models are used to for logical operation and resource files are used to perform actual database queries. Below are additions that we need to make the config.xml file, to include models in our module.

HTML Code:
<global>
    <models>
        <test>
            <class>Excellence_Test_Model</class> <!-- Location of all model class files -->
            <resourceModel>test_mysql4</resourceModel> <!-- Location of resource model -->
        </test>
        <test_mysql4>
            <class>Excellence_Test_Model_Mysql4</class>
            <entities>
                <test> 
                    <table>test_tablename</table>  <!-- Actual table name in sql  -->
                </test>
            </entities>
        </test_mysql4>
    </models>
    <resources>  <!-- These are resource setting giving access to module, read/write permission on database -->
        <test_setup>
            <setup>
                <module>Excellence_Test</module>
            </setup>
            <connection>
                <use>core_setup</use>
            </connection>
        </test_setup>
        <test_write>
            <connection>
                <use>core_write</use>
            </connection>
        </test_write>
        <test_read>
            <connection>
                <use>core_read</use>
            </connection>
        </test_read>
    </resources>
</global>
Explanation of important few sections added above.

HTML Code:
<entities>
   <test>  
        <table>test_tablename</table>  <!-- Actual table name in sql  -->
   </test>
</entities>
Here basically, we add a list of all our tables we would like to use in our module.
For example,

HTML Code:
<entities>
   <test>  
        <table>test_tablename</table>
   </test>
   <test2>  
        <table>test_tablename2</table>
   </test2>
   <test3>  
        <table>test_tablename3</table>
   </test3>
</entities>
As you will see ahead, in magento we reference all database table names using a different identifier, and in the tag, we defined the relation between magento table identifies and actual table name. For e.g.

“test/test” => test_tablename
“test/test2″ => test_tablename2
“test/test3″ => test_tablename3

Next we will create the model file. Lets create file Test.php in the model folder as follows

PHP Code:
<?php
class Excellence_Test_Model_Test extends Mage_Core_Model_Abstract
{
    public function 
_construct()
    {
        
parent::_construct();
        
$this->_init('test/test'); // this is location of the resource file.
    
}
}
It’s important to note here that ‘test/test’ in the $this->_init() function points to the location of the resource file.

Next we need to create the resource files, for that create a Mysql4 folder in Model folder.And then create a Test.php file inside Mysql4 folder.

So file location is \app\code\local\Excellence\Test\Model\Mysql4\Test. php

PHP Code:
<?php
class Excellence_Test_Model_Mysql4_Test extends Mage_Core_Model_Mysql4_Abstract
{
    public function 
_construct()
    {    
        
$this->_init('test/test''test_id');  // here test_id is the primary of the table test. And test/test, is the magento table name as mentioned in the       //config.xml file.
    
}
}
Again important to note here, that ‘test/test’ here is the magento table identifier we create in the config.xml file.

Now let’s create the sql file to create the database table. In the sql folder, create a sub folder called test_setup. And create a file called mysql4-install-0.1.0.php [here 0.1.0 is the version of the module as mentioned in the config.xml file.]

PHP Code:
<?php
$installer 
$this;  //Getting Installer Class Object In A Variable
$installer->startSetup();
$installer->run("
-- DROP TABLE IF EXISTS 
{$this->getTable('test')}
CREATE TABLE 
{$this->getTable('test')} (
  `test_id` int(11) unsigned NOT NULL auto_increment,
  `title` varchar(255) NOT NULL default '',
  `filename` varchar(255) NOT NULL default '',
  `content` text NOT NULL default '',
  `status` smallint(6) NOT NULL default '0',
  `created_time` datetime NULL,
  `update_time` datetime NULL,
  PRIMARY KEY (`test_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
"
);
$installer->endSetup();
?>
As you can see clearly, here we are creating the SQL table. One important thing to notice here is the function used for table name $this->getTable(‘test’). We use the getTable function here, so the table name automatically gets prefixed with the magento tables prefix (if any added during the installation process.). So, now our Model, Resource Model, and sql table are setup.

This sql file which is created is executed when any magento page is opened in the browser. They way it works is, there is a database table called, “core_resource”. This file maintains module version and name of each module loaded into magento. For example in our case module name would be test_setup i.e the folder of the sql files and module version is 0.0.1. What magento does is check the module version in database and the module version our config.xml file. If the version in config.xml greater than database version, it executes the corresponding sql file and update the module version in database.

In our case, we had already loaded the module before(in our previous blogs.), without the sql file. So, our db table already has the version 0.0.1 and also our current module version is also 0.0.1 , so our sql won’t get executed. You can test this by opening phpmyadmin and your new table won’t be created in the database, when you open magento. So, to execute our sql file, we need to remove the row of our module in the core_resource table of our module only and then open magento again.

Another way or rather the correct way to load sql file is, that we will increase our version number of our module to 0.0.2. So in our config.xml file in the tag, we will put in the version no 0.0.2. And similarly, we will create a new sql file named mysql4-upgrade-0.0.1-0.0.2.php. Now when we open our magento pages again, magento will check the ‘core_resource’ table, and in that table our module version number would be 0.0.1. But in our config.xml file we have updated our version number to 0.0.2, so magento will check if we have any sql update file and execute it. After executing it, the version in the ‘core_resource’ table will again be updated to the latest version. This will also give a hint on how magento update process works.

Save, Load and Delete Functions

All models in magento which inherit the class Mage_Core_Model_Abstract have save(), delete() and load() function, among many other important functions. Before going into these functions, there is another important thing to learn. Every model in magento you call any getter and setter function.

For eg. $model->setAbc() will work and $model->getAbc() will return the value. Similarly, $model->setManish(), $model->setCreatedDate() can be done. Another function to remember, is $model->getData(). This function returns an array, of all that has been ‘set’ in the models through the setter functions.

If you are wondering how these setters and getters are implemented, it done through php magic functions. And these are implemented in classes Varien_Object.

Save function is used to do the INSERT operation in a table. So, before saving a model, you need to first set all the values in the model. In our case.

PHP Code:
$model Mage::getModel(‘test/test’);
$model->setTitle(‘test title’);
$model->setFilename(‘filename’);
$model->setContent(‘abc abc abc’);
$model->setStatus(1);
$model->setCreatedTime(strtotime(‘now’));
$model->setUpdatedTime(strtotime(‘now’));
$model->save(); 
As you would notice, these are same as our database table columns. This will insert all these values into corresponding columns in the table. After, save operation is done. You will get the Primary Key (test_id) of the table.

For this you can do.

PHP Code:
$id $model->getTestId();
Or
$id $model->getId(); 
Load, function as the name suggests, is used to read a row from the table and set the values in the model.

For load function to work, you need to have primary key of the table. For eg.

PHP Code:
$test_id 3;
$model Mage::getModel(‘test/test’)->load($test_id);
echo 
$model->getTitle();
print_r($model->getData());
$model->setTitle(‘new title’);
$model->save();  //This will update the existing row in the table, for the primary key loaded with. This will not insert a new column. 
Delete, function will delete the row from the table, based on the primary key. So, if we do $model->delete() it will delete the row, for the primary key loaded in the model.

PHP Code:
$test_id 3;
$model Mage::getModel(‘test/test’)->load($test_id);
$model->delete(); 
_before and _after functions

As our model classes inherit Mage_Core_Model_Abstract, we get access to many useful function in our model classes. We have already discussed save(),load() and delete() functions. Other useful function are, _beforeSave(), _afterSave(), _beforeLoad(), _afterLoad(), _beforeDelete(), _afterDelete(). As the name suggests, these functions are called before and after their respective operations.

_beforeSave(): is called just before saving a model. So if you want to perform a validation before saving, you can do it here.

E.g if suppose before saving a User Model, we need to check for duplicate email address. So code for that would be like

PHP Code:
protected function _beforeSave()
    {
        
parent::_beforeSave();
        if(
$this->getResource()->checkDuplicate($this)){
           throw new 
Exception('User Email Already Exists');
        }
//$this->getResource()   returns the object of the resource model, where can put in the sql operations
        
return $this;
    } 
Similarly, we can use other functions as well.

Exercise:

1. Create a table UI in fronted magento to do Add/Edit/Delete/View operation on a database table.
2. Extend the previous question, to do Add/Edit/Delete/View operations on two tables.

View more threads in the same category: