Prepare the model

  1. Back to the file structure drawing board
    app/
      etc/
        modules/
          - SavantDegrees_All.xml (Or what ever your company name might be)
      code/
        local/
          SavantDegrees/ (Or what ever your company name might be)
            Twit/ (Or whatever your module name might be)
              Block/
                - Index.php
              controllers/
                - AdminController.php
                - IndexController.php
              etc/
                - config.xml
              Helper/
                - Data.php
              Model/
                - Twit.php
                Mysql4/
                  - Twit.php
                  Twit/
                    - Collection.php
              sql/
                twit_setup/
                  - mysql4-install-0.2.0.php
                  - mysql4-upgrade-0.1.0-0.2.0

    Notice the new folder Model and the associated files inside. Lets clarify:
    Model/Twit.php is the logical model that holds code regarding business logic and relations.
    Model/Mysql4/Twit.php is the data implementation model that associates the model with the table and its primary key.
    Model/Mysql4/Twit/Collection.php is the data implementation model of a collection of Twit. Similar to a recordset/resultset in .Net/Java. This will be used with a Grid later.

  2. Even more config.xml magic. Yay! More hairloss!
    <?xml version="1.0"?>
    <config>
        <modules>
            <SavantDegrees_Twit>
                <version>0.2.0</version>
            </SavantDegrees_Twit>
        </modules>
        <global>
            <models>
                <twit>
                    <class>SavantDegrees_Twit_Model</class>
                    <resourceModel>twit_mysql4</resourceModel>
                </twit>
                <twit_mysql4>
                    <class>SavantDegrees_Twit_Model_Mysql4</class>
                    <entities>
                        <twit>
                            <table>twit</table>
                        </twit>
                    </entities>
                </twit_mysql4>
            </models>
    	<blocks>
                <twit>
                    <class>SavantDegrees_Twit_Block</class>
                </twit>
            </blocks>
             <helpers>
                <twit><class>SavantDegrees_Twit_Helper</class></twit>
            </helpers>
            <resources>
                <twit_setup>
                    <setup>
                        <module>SavantDegrees_Twit</module>
                    </setup>
                    <connection>
                        <use>core_setup</use>
                    </connection>
                </twit_setup>
                <twit_write>
                    <connection>
                        <use>core_write</use>
                    </connection>
                </twit_write>
                <twit_read>
                    <connection>
                        <use>core_read</use>
                    </connection>
                </twit_read>
            </resources>
        </global>
        <adminhtml>
            <menu>
                <twit translate="title" module="twit">
                    <title>Twits</title>
                    <sort_order>100</sort_order>
                    <action>twit/admin</action>
                </twit>
            </menu>
        </adminhtml>
        <frontend>
            <routers>
                <SavantDegrees_Twit>
                    <use>standard</use>
                    <args>
                        <module>SavantDegrees_Twit</module>
                        <frontName>twit</frontName>
                    </args>
                </SavantDegrees_Twit>
            </routers>
        </frontend>
    </config>

    The global > models fragment define the twit table, the twit model and its resourceModel that we will be using shortly.

  3. Now for the model/Twit.php code:
    <?php
    class SavantDegrees_Twit_Model_Twit extends Mage_Core_Model_Abstract
    {
     
        protected function _construct()
        {
            $this->_init('twit/twit');
        }
    }

    Whats the point you ask!? The code does nothing but binds the model to the Twit namespace under the model twit. In Java that line would have been package Twit;. *i assume/think/foretold*
    (quickly moving on…)

  4. Then Model/Mysql4/Twit.php
    <?php
    class SavantDegrees_Twit_Model_Mysql4_Twit extends Mage_Core_Model_Mysql4_Abstract
    {
        protected function _construct()
        {
            $this->_init('twit/twit', 'twit_id');
        }
    }

    The code above tells Magento to hunt for the twit application’s twit table in the configuration. Yes i know the names are confusing now. Lets say instead of twit/twit it is twit/foo. In that case the system will find the configuration file associated with twit (which is our app/code/local/SavantDegrees/Twit/etc/config.xml), and look under config > global > models > twit_mysql4 > entities > foo to figure out its configuration instructions. You’ll see next that we’ll request for the table from that same configuration file. Capiche?
    As a resourceModel, the code binds the model to a underlying Mysql4 table.

  5. Lastly, Model/Mysql4/Twit/Collection.php
    <?php
    class SavantDegrees_Twit_Model_Mysql4_Twit_Collection extends Varien_Data_Collection_Db
    {
        protected $_twitTable;
     
        public function __construct()
        {
            $resources = Mage::getSingleton('core/resource');
            parent::__construct($resources->getConnection('twit_read'));
            $this->_twitTable = $resources->getTableName('twit/twit');
     
            $this->_select->from(
            		array('twit'=>$this->_twitTable),
     		       	array('*')
            		);
            $this->setItemObjectClass(Mage::getConfig()->getModelClassName('twit/twit'));
        }
    }

    Basically the model files created at this phase are simply trying to tie the model (singular and collection) to the underlying Mysql resource. The entire mechanism is half tied in the config.xml table declaration, the model individual instructions (from identifying the namespace to actually declaring the primary key of the table)

  6. Viola. Models are ready
Arent we there yet? Part 5 – CRUD – Retrieve

5 Responses to “Howto: Repackageable custom extension development in Magento – Part 4 – Model”

  1. Josh Ribakoff Says:

    If you get errors about calls to getConnection() on non object in abstract resource, check to make sure you used a slash in your _init() call on the mysql4 resource model

  2. Matt Says:

    I agree with tight. I got the error: “Call to undefined method SjTile_Hello_Model_Mysql4_Hello_Collection::_select()” until I modified it with tight’s suggestion to use _select->from

  3. tight Says:

    No, “$this->_select(” (without “from”) just doesn’t work for me

  4. gaweee Says:

    I understand the above is a shorthand to the same effect?

  5. tight Says:

    There’s a typo in Model/Mysql4/Twit/Collection.php, “$this->_select(” should be “$this->_select->from(”

Leave a Reply