Download the source for this entire series here!

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)
            Twits/ (Or whatever your module name might be)
              Block/
                - HelloWorld.php
              controllers/
                - AdminController.php
                - IndexController.php
              etc/
                - config.xml
              Helper/
                - Data.php
              Model/
                - Tip.php
                Mysql4/
                  - Tip.php
                  Tip/
                    - Collection.php
              sql/
                Twits_setup/
                  - mysql4-install-0.2.0.php
                  - mysql4-upgrade-0.1.0-0.2.0.php

    Notice the new folder Model and the associated files inside. Lets clarify:
    Model/Tip.php is the logical model that holds code regarding business logic and relations.
    Model/Mysql4/Tip.php is the data implementation model that associates the model with the table and its primary key.
    Model/Mysql4/Tip/Collection.php is the data implementation model of a collection of Tip. 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_Twits>
                <version>0.2.0</version>
            </SavantDegrees_Twits>
        </modules>
        <global>
            <models>
                <twits>
                    <class>SavantDegrees_Twits_Model</class>
                    <resourceModel>twits_mysql4</resourceModel>
                </twits>
                <twits_mysql4>
                    <class>SavantDegrees_Twits_Model_Mysql4</class>
                    <entities>
                        <tip>
                            <table>tips</table>
                        </tip>
                    </entities>
                </twits_mysql4>
            </models>
    	<blocks>
                <twits>
                    <class>SavantDegrees_Twits_Block</class>
                </twits>
            </blocks>
             <helpers>
                <twits><class>SavantDegrees_Twits_Helper</class></twits>
            </helpers>
            <resources>
                <twits_setup>
                    <setup>
                        <module>SavantDegrees_Twits</module>
                    </setup>
                    <connection>
                        <use>core_setup</use>
                    </connection>
                </twits_setup>
                <twits_write>
                    <connection>
                        <use>core_write</use>
                    </connection>
                </twits_write>
                <twits_read>
                    <connection>
                        <use>core_read</use>
                    </connection>
                </twits_read>
            </resources>
        </global>
        <adminhtml>
            <menu>
                <twits translate="title" module="twits">
                    <title>Twits</title>
                    <sort_order>100</sort_order>
                    <action>twits/admin</action>
                </twits>
            </menu>
        </adminhtml>
        <frontend>
            <routers>
                <SavantDegrees_Twits>
                    <use>standard</use>
                    <args>
                        <module>SavantDegrees_Twits</module>
                        <frontName>twits</frontName>
                    </args>
                </SavantDegrees_Twits>
            </routers>
        </frontend>
    </config>

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

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

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

  4. Then Model/Mysql4/Tip.php
    <?php
    class SavantDegrees_Twits_Model_Mysql4_Tip extends Mage_Core_Model_Mysql4_Abstract
    {
        protected function _construct()
        {
            $this->_init('twits/tip', 'tip_id');
        }
    }

    The code above tells Magento to hunt for the twits application’s twits table in the configuration. Yes i know the names are confusing now. Lets say instead of twits/tip it is twits/foo. In that case the system will find the configuration file associated with twits (which is our app/code/local/SavantDegrees/Twits/etc/config.xml), and look under config > global > models > twits_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/Tip/Collection.php
    <?php
    class SavantDegrees_Twits_Model_Mysql4_Tip_Collection extends Varien_Data_Collection_Db
    {
        protected $_tipTable;
     
        public function __construct()
        {
            $resources = Mage::getSingleton('core/resource');
            parent::__construct($resources->getConnection('twits_read'));
            $this->_tipTable= $resources->getTableName('twits/tip');
     
            $this->_select->from(
            		array('tip'=>$this->_tipTable),
     		       	array('*')
            		);
            $this->setItemObjectClass(Mage::getConfig()->getModelClassName('twits/tip'));
        }
    }

    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