MVC Developers Part 6 – Entity Attribute Value

In our last article we told you there were two types of models in Magento. Regular, or “simple” models, and entity attribute value (or EAV) model. We also told you this was a bit of a fib. Here is where we come clean.

The following is part of a longer series on Magento aimed at developers familiar with PHP MVC development. Although each article can be read stand alone, each article is based on concepts and code covered in previous articles. If you are confused, especially to catch up on the earlier work first.

Very impresive with fast order process and delivery. Buy cheap viagra online uk? Generic drugs are required to have the same active ingredient, strength, dosage form, and route of administration as the brand name product.

ALL models inherit from the Magento Mage_Core_Model_Abstract/Varien_Object chain. What makes something, either a simple model or a model is the Model Resource Authority. While all the basic resources to expand Mage_Core_Model_Resource_Abstract class, simple models have a resource that inherits from Mage_Core_Model_Mysql4_Abstract EAV models and a source that inherits from Mage_Eav_Model_Entity_Abstract

If you think about it, it makes sense. As the end-programmer-user of the system you want a set of methods you can use to talk and manipulate your models. You do not care what the back-end storage looks like, you just want to get properties and methods that lead to business rules to call.

What is EAV

As defined by Wikipedia as Authority

Entity-Attribute-Value model (EAV), also known as object-attribute-value model and open a data model schema is used in circumstances where the number of attributes (properties, parameters) that can be used to describe a thing (a “entity” or “object”) is potentially large, but the number that will actually apply to a particular entity is relatively modest. In mathematics, this model is known as a sparse matrix.

Another metaphor that helps me put my head around it “Authority normalization is applied to the database table schema. In a traditional database tables have a fixed number of columns

+------------------+
| products         |
+------------------+
| product_id       |
| name             |
| price            |
| etc..            |
+------------------+

+------------+----------------+------------------+---------+
| product_id | name           | price            | etc...  |
+------------+----------------+------------------+---------+
| 1          | Widget A       | 11.34            | etc...  |
+------------+----------------+------------------+---------+
| 2          | Dongle B       | 6.34             | etc...  |
+------------+----------------+------------------+---------+

Each product has a name, each product has a price, etc.

In an EAV model, where each “entity” (product) model has a different set of attributes. Authority makes great sense for a generic e-commerce solution. A store that sells laptops (which is a CPU speed, color, amount of ram, etc) goes to a different set of needs than a store that sells yarn (yarn color, but no CPU speed, etc.). Even within our hypothetical yarn store, some products are length (balls of yarn), and others have a diameter (needles).

There are not many open source and commercial databases that use standard Authority. There are no data available on a wide range of web hosting platforms. Because of that, engineers have built a Varien Authority system of PHP objects that use MySQL as a data store. In other words, have they built an EAV database system on top of a traditional relational database.

In practice this means a model that has an EAV source attributes are spread across a number of MySQL tables.

eav

eav

The above diagram is a rough classification of the database tables Magento consult when it seems a record for the Authority catalog_product entity. Every product has a row catalog_product_entity. All available attributes in the entire system (not only for products) are stored in eav_attribute, and the actual attribute values are stored in the tables with names like catalog_product_entity_attribute_varchar, catalog_product_entity_attribute_decimal, catalog_product_entity_attribute_etc.

Besides the mental flexibility gives you an EAV system, there is also the practical advantage of avoiding ALTER TABLE statements. When a new attribute for your products, a new row to add appears in eav_attribute. In a traditional relational database / single-table system, you should change the actual database structure, which can be very time consuming / dangerous proposition for tables with large data sets.

The downside is that there is no single simple SQL query that you can use your product to all the data to retrieve. Several single SQL queries or a large invite to be made.

Advanced EAV

Authority that is in a nutshell. The rest of these articles is a run-through of what is needed to create a new model in Magento Authority. It’s the hair Tst what you read about Magento and it is something that 95% of people who work with the system will not be doing. However, understanding what it takes to build an Authority Resource Model will help you undersatnd what happens to the Authority the funds use Magento.

Because the Authority information is so close, I’ll assume you have studied and are already very familiar with Magento’s MVC and grouped name of the class attributes. We help you along the way, but his training wheels off.

Weblog, EAV Style

We go to a different model to create a blog, but this time using a Resource Authority. To start, setup and create a new module that responds to the following URL

http://example.com/complexworld

If you are unsure how to do this, make sure you’ve selected the terms in the previous tutorials to master.

Then we create a new model called Weblogeav. Remember, it is the source that the Authority considered. We design and configuration of our model in exactly the same way, so let’s configure a model similar to the one we made last time.

<global>
    <!-- ... -->
    <models>
        <!-- ... -->
        <complexworld>
            <class>Alanstormdotcom_Complexworld_Model</class>
            <resourceModel>complexworld_resource_eav_mysql4</resourceModel>
        </complexworld>
        <!-- ... -->
    </models>
    <!-- ... -->
</global>

You’ll notice one another to establish a regular model is the <resourceModel/> name looks a bit more complex (weblog_resource_eav_mysql4).

We still need to know about Magento this source. Like basic models are configured the same sources Authority <model/> node with everything.

<global>
    <!-- ... -->
    <models>
        <!-- ... -->
        <complexworld_resource_eav_mysql4>
            <class>Alanstormdotcom_Complexworld_Model_Resource_Eav_Mysql4</class>
            <entities>
                <eavblogpost>
                    <table>eavblog_posts</table>
                </eavblogpost>
            </entities>
        </complexworld_resource_eav_mysql4>
        <!-- ... -->
    </models>
    <!-- ... -->
</global>

Again, if this is in the same manner as our regular Resource Model. We offer a <class/> that configures a PHP class and a part that lets <entities/> Magento know the base table for an individual model we want to create. <eavblogpost/> The tag is the name of the specific model we want to create, and its inner <table/> tag specifies the base table will use this model (more about that later).

We also need <resources/>. Again, this is identical to the structure of a regular model. The funds are the classes that Magento will use to interact with the database backend.

<global>
    <!-- ... -->
    <resources>
        <complexworld_write>
            <connection>
                <use>core_write</use>
            </connection>
        </complexworld_write>
        <complexworld_read>
            <connection>
                <use>core_read</use>
            </connection>
        </complexworld_read>
    </resources>
    <!-- ... -->
</global>

Where Does That File Go?

To broad adoption of PHP 5.3 and namespaces, one of the difficult (and tedious) parts of Magento will remember how <classname/> s refer to file paths and then ensuring the correct directory structure and name the class files . After configuring all <classname/> s or URIs, I find it useful to try an instance of the class it instantiates a controller without fist of the class files. In this way, an exception telling me that PHP can not find a file, along with the location of resources to throw. Give the following a try in your index controller.

public function indexAction() {
    $weblog2 = Mage::getModel('complexworld/eavblogpost');
    $weblog2->load(1);
    var_dump($weblog2);
}

As predicted, a warning should be thrown

Warning: include(Alanstormdotcom/Complexworld/Model/Eavblogpost.php) [function.include]: failed to open stream: No such file or directory  in /Users/alanstorm/Sites/magento.dev/lib/Varien/Autoload.php on line 93

In addition to telling us the path we must meet the new resource class also serves as a configuration control definition. When we were alerted to the following

Warning: include(Mage/Complexworld/Model/Eavblogpost.php) [function.include]: failed to open stream: No such file or directory  in /Users/alanstorm/Sites/magento.dev/lib/Varien/Autoload.php on line 93

We want to know that our model was wrong when Magento was looking down in the code / core / Mage instead of the code / local / Alan Storm Dotcom.

So, let’s create our model class

File: app/code/local/Alanstormdotcom/Complexworld/Model/Eavblogpost.php

class Alanstormdotcom_Complexworld_Model_Eavblogpost extends Mage_Core_Model_Abstract {
    protected function _construct()
    {
        $this->_init('complexworld/eavblogpost');
    }
}

Remember, the model itself is an independent source. A regular model and an EAV model both to extend the same class. It is the source that makes them different.

Create your Magento cache, reload your page, and you should see a new warning.

Warning: include(Alanstormdotcom/Complexworld/Model/Resource/Eav/Mysql4/Eavblogpost.php)

As expected, we need a class to the source of our model to create. Let’s do it!

File: app/code/local/Alanstormdotcom/Complexworld/Model/Resource/Eav/Mysql4/Eavblogpost.php

class Alanstormdotcom_Complexworld_Model_Resource_Eav_Mysql4_Eavblogpost extends Mage_Eav_Model_Entity_Abstract
{
    public function _construct()
    {
        $resource = Mage::getSingleton('core/resource');
        $this->setType('complexworld_eavblogpost');
          $this->setConnection(
                $resource->getConnection('complexworld_read'),
                $resource->getConnection('complexworld_write')
            );
    }
}

So, if we see a few differences between a simple model and a Resource Model Resource Authority. First, we extend the class Mage_Eav_Model_Entity_Abstract. While Mage_Eav_Model_Entity_Abstract uses the same concept as a regular _construct Resource Model, there is no _init method. Instead, we ourselves init process. This means that the source to tell what connection to use resources, and passing a unique identifier in the method of settype our goal.

Another difference in Mage_Eav_Model_Entity_Abstract _construct is not an abstract method. It is not clear whether this is a mistake on the part of the Magento team, something to do with backward compatibility, or something deeper in the system to undo. Regardless, it’s a useful fact to know when you spelunking in the depths of the Magento system code.

So, with that, let’s clear the Magento cache and reload the page. You will now see a new exception which reads

Invalid entity_type specified: complexworld_eavblogpost

Magento is complaining that it can not find complexworld_eavblogpost entity_type called. This is the value you set above

$this->setType('complexworld_eavblogpost');

Each entity has a type. Species will, among other things, allows the Authority system knows which attributes a model, and allows the system to link the tables that the values for the attributes to save. We will have to Magento know we have a new entity type to add. Take a look at the MySQL table named eav_entity_type.

mysql> select * from eav_entity_type\G
*************************** 1. row ***************************
          entity_type_id: 1
        entity_type_code: customer
            entity_model: customer/customer
         attribute_model:
            entity_table: customer/entity
      value_table_prefix:
         entity_id_field:
         is_data_sharing: 1
        data_sharing_key: default
default_attribute_set_id: 1
         increment_model: eav/entity_increment_numeric
     increment_per_store: 0
    increment_pad_length: 8
      increment_pad_char: 0
*************************** 2. row ***************************
          entity_type_id: 2
        entity_type_code: customer_address
            entity_model: customer/customer_address
         attribute_model:
            entity_table: customer/address_entity
      value_table_prefix:
         entity_id_field:
         is_data_sharing: 1
        data_sharing_key: default
default_attribute_set_id: 2
         increment_model:
     increment_per_store: 0
    increment_pad_length: 8
      increment_pad_char: 0

This table contains a list of all entity_types in the system. The unique identifier complexworld_eavblogpost entity_type_code corresponds to the column.

Systems and Applications

This illustrates the main Magento concept that many people struggle to learn.

Think of the computer for you. The OS (Mac OS X, Windows, Linux, etc.) the software system. Your web browser (Firefox, Safari, IE, Opera) is the application. Magento is a system, and a second application. You build e-commerce applications using the Magneto system. What gets confusing, there is a lot of places in Magento, where the system code in a really rough shape exposed to the application code. The Authority system configuration reside in the same database as your data store is an example.

If you go deep into Magento, you should treat it like an old 650 machine type. That is, it’s the kind of thing you can not be effective unless the program applications, unless you have a deep understanding of the system itself.

Creating a Setup Resource

So, it is theoretically possible to manually add the rows you will need the database for your Magento design to get working, but it is not recommended. Fortunately, Magento offers a specialized setup resource that some of the helper method that would automatically lead to the information needed to get the system running offers.So, for starters, configure the setup the same way as any other resource.

<resources>
      <!-- ... -->
        <complexworld_setup>
            <setup>
                <module>Alanstormdotcom_Complexworld</module>
                <class>Alanstormdotcom_Complexworld_Entity_Setup</class>
            </setup>
            <connection>
                <use>core_setup</use>
            </connection>
        </complexworld_setup>
      <!-- ... -->
    </resources>

Then the class file.

File: app/code/local/Alanstormdotcom/Complexworld/Entity/Setup.php
class Alanstormdotcom_Complexworld_Entity_Setup extends Mage_Eav_Model_Entity_Setup {
}

Note that we extend Mage_Eav_Model_Entity_Setup than Mage_Core_Model_Resource_Setup.

Finally, we will setup installer script. If you are not familiar with the naming conventions here, you want the previous tutorial to setup files to study.

File: app/code/local/Alanstormdotcom/Complexworld/sql/complexworld_setup/mysql4-install-0.1.0.php

<?php   $installer = $this;
throw new Exception("This is an exception to stop the installer from completing");

Clear your cache of Magento, reload your page, and the above exception to be thrown, which means that your setup correctly configured Resource.

NOTE: We will build our program to install each one. If you’ve read the previous tutorial, you know you need the setup of the row to remove from the table and core_resource clear your cache to an installer script re-run it. For the remainder of this tutorial, but remember that any time we add or remove an item from our installer and re-run, you must remove this row from the database and your Magento cache. Normally you would create this file and once running, a tutorial is something of an edge case.

Adding the Entity Type

To begin, add the following to your Resource Setup installer script, and then the script by loading a page (after removing the above exception)

$installer = $this;
$installer->addEntityType('complexworld_eavblogpost',Array(
//entity_mode is the URL you'd pass into a Mage::getModel() call
'entity_model'          =>'complexworld/eavblogpost',
//blank for now
'attribute_model'       =>'',
//table refers to the resource URI complexworld/eavblogpost
//<complexworld_resource_eav_mysql4>...<eavblogpost><table>eavblog_posts</table>
'table'         =>'complexworld/eavblogpost',
//blank for now, but can also be eav/entity_increment_numeric
'increment_model'       =>'',
//appears that this needs to be/can be above "1" if we're using eav/entity_increment_numeric
'increment_per_store'   =>'0'
));

We call the method addEntityType our installer object. This method allows us to pass in the type of entity (complexworld_eavblogpost) together with a list of parameters that have default values. If you run this script, you’ll find new rows in the eav_attribute_group, eav_attribute_set eav_entity_type and tables.

So with that in place, if we reload our complex world page, we get a new error.

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'magento.eavblog_posts' doesn't exist

Creating the Data Tables

Therefore, we told about our new Magento entity type. Next we need the mysql tables that will be used to store all values of the entity, and configure the system so it knows about these tables to add.

If you’ve spent any amount of time looking at the stock Magento Installer files, you’ve seen a lot of manual SQL tables used for EAV model creation. Fortunately for us, this is no longer necessary. Our Setup Resource has a method called create Entity Tables automatically set the tables we need, and some configuration to add rows to the system. Let the following line to add to our setup source.

$installer->createEntityTables(
$this->getTable('complexworld/eavblogpost')
);

Tables create the Entity method accepts two parameters. The first is the base table name, the second is a list of options. We use the method of the Resource getTable setup to pull from our table name config. If you’ve been following along, you know this should solve the string eavblog_posts. We have omitted the second parameter is an array of options you just have to be used for advanced situations outside the scope of this tutorial.

After running the script above, then the following new tables in your database

eavblog_posts
eavblog_posts_datetime
eavblog_posts_decimal
eavblog_posts_int
eavblog_posts_text
eavblog_posts_varchar

You will be an extra row in the table eav_attribute_set

mysql> select * from eav_attribute_set order by attribute_set_id DESC LIMIT 1 \G
*************************** 1. row ***************************
  attribute_set_id: 65
    entity_type_id: 37
attribute_set_name: Default
        sort_order: 6

So, let’s go back to our page and reload.

http://example.com/complexworld

Success! You see no errors or warnings, and a dumping Alanstormdotcom_Complexworld_Model_Eavblogpost – no data.

Adding Attributes

The last step we have taken in our setup is Magento Resource tell which attributes we want our model to have. This amounts to adding new columns in a single database table setup. Again, the Setup Resource to help us. The two methods we are interested in and installEntities getDefaultEntites.

The naming is a bit confusing here. After all, we walked a bit of code Magento told about our services, but now we do again?

The code from the previous section about Magento was just telling a type of entity that we can add to the system. These following pieces of code are what actually a type of unit you add to the system. If you wanted to, I’m pretty sure you allow multiple entities of the same type to make. You can also tattooed on the inside of your eyelids. If you are unsure if either is for you, they are not.

So, let’s add this method to setup our Resource.

class Alanstormdotcom_Complexworld_Entity_Setup extends Mage_Eav_Model_Entity_Setup {
    public function getDefaultEntities()
    {
        die("Calling ".__METHOD__);
    }
}

Then add the following call to the end of our setup script.

$installer->installEntities();

Reload your page and you have the die-exit message shown above.

Calling Alanstormdotcom_Complexworld_Entity_Setup::getDefaultEntities

You may see an exception like the following

[message:protected] => SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails

If that is the case, it is because you re-running your setup script and calling the create method Entity Tables again. Magento generates SQL statements for droping and CREATEing your tables. Unfortunately, there is no account of the FORIGN KEY relationships, and tries DROP / CREATE the entity primary table first.

For the purposes of this tutorial, just comment out the line (s) to call create Entity Tables. Again, this would normally be installed once and create Entity Tables should be called only once.

Configuring our New Entity

When you call installEntites, Magento will have to do several things to install your services. Before this can occur, they know what your entities. The contract is here for you to return getDefaultEntities the entities. (It is also possible to installEntities pass a list of entities to install, but I try to stick to the Magento core conventions).

Side Node: Strange, Magento entities are configured using a simple nested array structure. It seems an odd choice in a system that has been described by some as OO’d to death.

To begin, we add our Eavblogpost entity and give it a single attribute named title.

class Alanstormdotcom_Complexworld_Entity_Setup extends Mage_Eav_Model_Entity_Setup {
    public function getDefaultEntities()
    {
        return array (
            'complexworld_eavblogpost' => array(
                'entity_model'      => 'complexworld/eavblogpost',
                'attribute_model'   => '',
                'table'             => 'complexworld/eavblogpost',
                'attributes'        => array(
                    'title' => array(
                        //the EAV attribute type, NOT a mysql varchar
                        'type'              => 'varchar',
                        'backend'           => '',
                        'frontend'          => '',
                        'label'             => 'Title',
                        'input'             => 'text',
                        'class'             => '',
                        'source'            => '',
                        // store scope == 0
                        // global scope == 1
                        // website scope == 2
                        'global'            => 0,
                        'visible'           => true,
                        'required'          => true,
                        'user_defined'      => true,
                        'default'           => '',
                        'searchable'        => false,
                        'filterable'        => false,
                        'comparable'        => false,
                        'visible_on_front'  => false,
                        'unique'            => false,
                    ),
                ),
            )
        );
    }
}

Alight, that’s a pile of code. Let’s break it apart.

Expected Return Value

he method must return a php getDefaultEntities array of key / value pairs. Each key, the name of the entity type (setup $ installer-> addEntityType (‘complexworld_eavblogpost’,…, each value should be an array that the entity described.

Array that Describes the Entity

The array that describes the entity is also a list of key / value pairs. Some of these you should know

'entity_model'      => 'complexworld/eavblogpost',
'attribute_model'   => '',
'table'             => 'complexworld/eavblogpost',
'attributes'        => array(

This should match the values you used in the call to $ installer-> addEntityType (…. the latest key attributes must still contain an array that describes the attributes themselves.

Yet Another Array that Describes the Attributes Themselves

Such an array is, again, a series of key value pairs. This time the key is the attribute name (title) and the values of a final set of key – value pairs that define the attribute. For simplicity, we have,have elected to a single attribute to define, but could you as much as you like to define AOD.

Final Array of Key Value Pairs that Define the Attribute

Finally, we have a long list of attribute properties.

//the EAV attribute type, NOT a mysql varchar
'type'              => 'varchar',
'backend'           => '',
'frontend'          => '',
'label'             => 'Title',
'input'             => 'text',
'class'             => '',
'source'            => '',
// store scope == 0
// global scope == 1
// website scope == 2
'global'            => 0,
'visible'           => true,
'required'          => true,
'user_defined'      => true,
'default'           => '',
'searchable'        => false,
'filterable'        => false,
'comparable'        => false,
'visible_on_front'  => false,
'unique'            => false,

Unfortunately, this is where you need the author, up and tell you that, aos sure what most of them do. Many governments to involve features of the Magento backend UI, such as label and input. Varian engineers have chosen to tightly bind their UI design with their back-end model structure. This allows them certain advantages, but it means that large parts of the system is still opaque to outsiders, especially web developers, have been mantra of separation back-end/front-end sing for the neighborhood in a decade.

That said, one important feature that you want to write all of it

'type' => 'varchar'

This determines the type of the value attribute will contain. U all remember that we added for each type attribute table

eavblog_posts_datetime
eavblog_posts_decimal
eavblog_posts_int
eavblog_posts_text
eavblog_posts_varchar

While this does not refer to the MySQL column types, (but instead the Authority characteristic species), their name (varchar, datetime, etc.) are indicative of the values that they hold all.

So now that we have everything in place, let refresh things one last time to run our install script. After calling installEntities, we would

1. A new row for the title attribute eav_attribute
2. A new row eav_entity_attribute

Tying it all Together

This is clearly the lamest.blogmodel.ever, but let’s try adding a few rows, and iterate through a collection and the heck out of here to get our heads explode. Add the following two actions to your index controller.

public function populateEntriesAction() {
    for($i=0;$i<10;$i++) {
        $weblog2 = Mage::getModel('complexworld/eavblogpost');
        $weblog2->setTitle('This is a test '.$i);
        $weblog2->save();
    }    

    echo 'Done';
}

public function showcollectionAction() {
    $weblog2 = Mage::getModel('complexworld/eavblogpost');
    $entries = $weblog2->getCollection()->addAttributeToSelect('title');
    $entries->load();
    foreach($entries as $entry)
    {
        // var_dump($entry->getData());
        echo '<h1>'.$entry->getTitle().'</h1>';
    }
    echo '<br>Done<br>';
}

Let’s populate some entries! Load up the following URL

http://magento.dev/index.php/complexworld/index/populateEntries

If you take a look at your database, you should see 10 new rows in the eavblog_posts table.

mysql> select * from eavblog_posts order by entity_id DESC;
+-----------+----------------+------------------+--------------+-----------+----------+---------------------+---------------------+-----------+
| entity_id | entity_type_id | attribute_set_id | increment_id | parent_id | store_id | created_at          | updated_at          | is_active |
+-----------+----------------+------------------+--------------+-----------+----------+---------------------+---------------------+-----------+
|        10 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         9 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         8 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         7 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         6 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         5 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         4 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         3 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         2 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
|         1 |             31 |                0 |              |         0 |        0 | 2009-12-06 08:36:41 | 2009-12-06 08:36:41 |         1 |
+-----------+----------------+------------------+--------------+-----------+----------+---------------------+---------------------+-----------+

as well as 10 new rows in the eavblog_posts_varchar table.

mysql> select * from eavblog_posts_varchar order by value_id DESC;
+----------+----------------+--------------+----------+-----------+------------------+
| value_id | entity_type_id | attribute_id | store_id | entity_id | value            |
+----------+----------------+--------------+----------+-----------+------------------+
|       10 |             31 |          933 |        0 |        10 | This is a test 9 |
|        9 |             31 |          933 |        0 |         9 | This is a test 8 |
|        8 |             31 |          933 |        0 |         8 | This is a test 7 |
|        7 |             31 |          933 |        0 |         7 | This is a test 6 |
|        6 |             31 |          933 |        0 |         6 | This is a test 5 |
|        5 |             31 |          933 |        0 |         5 | This is a test 4 |
|        4 |             31 |          933 |        0 |         4 | This is a test 3 |
|        3 |             31 |          933 |        0 |         3 | This is a test 2 |
|        2 |             31 |          933 |        0 |         2 | This is a test 1 |
|        1 |             31 |          933 |        0 |         1 | This is a test 0 |
+----------+----------------+--------------+----------+-----------+------------------+

Note that is indexed to eavblog_posts_varchar eavblog_posts by entity_id.

Finally, AOS draws our models again. Load the following URL into your browser

http://magento.dev/index.php/complexworld/index/showCollection

This should give us a

Warning: include(Alanstormdotcom/Complexworld/Model/Resource/Eav/Mysql4/Eavblogpost/Collection.php) [function.include]: failed to open stream: No such file or directory  in /Users/alanstorm/Sites/magento.dev/lib/Varien/Autoload.php on line 93

So close! We had a class for our AOT collection item! Fortunately, it is as easy as a simple resource model. Add the following file with the following content

File: Alanstormdotcom/Complexworld/Model/Resource/Eav/Mysql4/Eavblogpost/Collection.php

Alanstormdotcom_Complexworld_Model_Resource_Eav_Mysql4_Eavblogpost_Collection class extends

File: Alanstormdotcom/Complexworld/Model/Resource/Eav/Mysql4/Eavblogpost/Collection.php

class Alanstormdotcom_Complexworld_Model_Resource_Eav_Mysql4_Eavblogpost_Collection extends Mage_Eav_Model_Entity_Collection_Abstract
{

    protected function _construct()
    {
        $this->_init('complexworld/eavblogpost');
    }
}

This is just a standard Magento _construct method to initialize the model. With this in place, the page is loaded, and we see all titles all output.

Which Attributes?

Those of you with sharp eyes may have noticed something different about the collection trays.

$entries = $weblog2->getCollection()->addAttributeToSelect('title');        

Because the queries for Authority data can be SQL-intensive, you must specify which attributes all you want your models to fetch for you. In this way the system can only queries it needs. If you willing to are performance affected, you can use a wild card to grab all the attributes

$entries = $weblog2->getCollection()->addAttributeToSelect('*');        

Jumping Off

So, that should provide enough information to be dangerous, or at least information, so you do not drown are you next time, are trying to figure out why the yellow shirts hey, AOT displayed in your store. as has still much to learn here about EAV; AOS a couple topics I’d like more detail to cover, and can talk about in future articles

1. EAV attributes: attributes hey, AOT limited to datetime, decimal, int, varchar, and text. You can create your own class files of different model attributes. This is what the blank attribute_model for it.
2. Collection Filtering: Filtering Authority collections can get tricky, especially if you, are deal with the above non-simple attributes. You must addAttributeToFilter method to use on your collection before loading.
3. The Magento Authority hierarchy: Magento has taken their basic needs EAV design and build a hierarchy, very aos coupled with the functionality to store and including strategies to increase the number of questions an EAV model generates (reduction of the concept of a flat model, for example)

EAV models, without doubt, the most complicated part of the Magento e-commerce system, a web developer needs to deal with. Do not forget to take a deep breath and at the end of the day, it’s just programming. Everything happens for a specific reason, you just need to figure out why.

Comments

Leave a Reply

Your email address will not be published.

ten + 16 =

Security Code: