Magento – About Collection Model and Resource Model

collection;magento-1.7product-listresource-model

I am bit confused about using resource model and collection model. Sometimes when I see examples for loading products using specific attributes, in some examples, they use collection model and sometimes they use resource model.

Also when can I use specific method get... and set... along with table row name? Like getName, getId. I tried to use but unable get the values and it shows error: "calling undefined method in object"

$product = Mage::getModel('catalog/product')
    ->loadByAttribute('name', 'product_name');

echo $product->getName(); 
echo $product->getSku();

It shows "undefined method getSku()"

If I use var_dump($product), SKU shows in object, however unable to get the SKU using getSku()

Best Answer

Magento's CRUD models have three basic class types.

A "model" is what you'll most commonly use. This represents data of a particular type in a database agnostic way (product, category, CMS Page, Review, etc.)

A "resource model" is a class that, behind the scenes, does the actual fetching of data from Magento. Every model has a resource model that is used to load a single instance of a model from the database.

A "collection" is a class that loads an array like structure of multiple models based on a set of rules. Think of it like a SQL WHERE clause.

Confusing things somewhat is, behind the scenes, Magento also considers a collection to be a resource model. So there's collection resource models and individual resource models.

Generally speaking, when you want to load a specific item, you use a model. When you want to load a number of items, you use a collection resource model.

//loads one
$product = Mage::getModel('catalog/product')->load($id);

//loads many products where price is greater than 100
$products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*') //load all fields, see EAV below
->addAttributeToFilter('price', array('gt'=>'100'));

foreach($products as $product)
{
    var_dump($product->getSku());
}

One thing to keep in mind about loading via a collection resource model is each individual model's afterLoad method won't be called automatically, which means some data may not be loaded.

The individua resource model classes are usually not accessed directly. However, occasionally a specific model will have a resource model with a useful method on it. These you'll discover over time using the system.

Finally, there's one more distinction to be made. Magento's regular CRUD models have a special syntax for loading via something that's not the numeric ID. For example, here's how to load a CMS page model by title

$page = Mage::getModel('cms/page')->load('Home page','title');
var_dump($page->getData());

However, a few Magento models are EAV models. That stands for "entity attribute value", and is a fancy way of saying these models don't have a fixed set of fields. This includes product models, and category models. This feature is what lets you pick different attributes for different types of products. Each field on an EAV model is known as an attribute. The above syntax won't work with these models, instead you need to use the loadByAttribute method.

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'n2610');

Regarding your specific problem, if you're getting an error with the specific text "method undefined", then something is very wrong with your system. Even if the getSku method doesn't exist, Magento has magic setter and getter methods which ensure a get call on any model will always return something, even if it's null.

What's more likely is you're getting an error like the following

Call to a member function getSku() on a non-object

This error is happening because the loadByAttribute method returns false if it can't load the object.

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'this-is-not-a-sku');
var_dump($product); //prints false

Try something like this in your code.

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'sku-value');
if($product)
{
    var_dump($product->getName());
    var_dump($product->getSku());
    var_dump($product->getData());
}
else
{
    var_dump("Could not load product");
}

In additional to the conditional, notice the getData() method. This will return an array of all the object's data as an array.

Hopefully this is enough to get you moving. Good luck!