Creating and Instantiating a Model

When you want to create a new (basic) model class in Magento, there are only a few things you need to know:

1. Extend the right class.

2. Make sure the config.xml is set up correctly.

Extending the right class

If you are mapping this model to a database table, you should be extending Mage_Core_Model_Abstract or one of its children.

If you are just creating a model to hold some business logic and the model doesn’t map to a table, extend Varien_Object.

If you get this first part right, a majority of your coding is already written for you.

Make sure the config.xml is set up correctly

Because we instantiate model objects using the factory Mage::getModel(), we need to make sure a couple of things are set up in the config.xml correctly. In this example, let’s pretend we have a model called: Super_Awesome_Model_Example. Because of the Magento framework, we can assume that this model would be in the “Awesome” module, inside the “Super” namespace. We might also assume that the call to get the model would look like this: Mage::getModel(‘awesome/example’);. This assumption may not be true however. It ALL depends on the config.xml.

If the config.xml is written as follows, then you will end up with the correct model object.

<config>
   ....
    <global>
        <models>
            <awesome>
                <class>Super_Awesome_Model</class>
            </awesome>
    </global>
</config>

However, the config.xml could just as easily be written as follows, in which case you will get an error because you can’t find the modal class anywhere:

<config>
   ....
    <global>
        <models>
            <blah>
                <class>Super_Awesome_Model</class>
            </blah>
    </global>
</config>

In the case above, the way to get the Super_Awesome_Model_Example would be: Mage::getModel(‘blah/example’);

You see, the first part of the “class alias” (‘blah’) doesn’t necessarily map to the module in ANY way. Generally, if you are not crazy, you will name it close, or the same as the module name, but there is nothing forcing that. The snippet of code that constructs the name of the class to be instantiated can be found in Mage_Core_Model_Config->getGroupedClassName():

        $config = $this->_xml->global->{$groupType.'s'}->{$group};

        if (isset($config->rewrite->$class)) {
            $className = (string)$config->rewrite->$class;
        } else {
            if (!empty($config)) {
                $className = $config->getClassName();
            }
            if (empty($className)) {
                $className = 'mage_'.$group.'_'.$groupType;
            }
            if (!empty($class)) {
                $className .= '_'.$class;
            }
            $className = uc_words($className);
        }

        $this->_classNameCache[$groupRootNode][$group][$class] = $className;
        return $className;

In our (second) example, the first line would read:

$config = $this->_xml->global->models->blah

…and would return back the configuration (which includes the prefix for the name of the class).

As a side note, the reason we ALWAYS use the factory Mage::getModel() (instead of new Class_Name) is to support the ability to override/extend/rewrite within the Magento framework. Following this coding standard can/will save you heartaches in the future.

Leave a Reply

Your email address will not be published.

4 × 4 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>