Magento2 Best Practice – Get Collection Efficiently

best practicecollection;factorymagento2

I know it is not a good practice to use objectManager to get collection. However, I don't know what is the advantage of using ModelFactory ($this->mymodelFactory->create()->getCollection()) over injecting Collection class directly in to the constructor?

For example following two codes generates same results:

Using Factory:

<?php

namespace Unit4\Module6\Controller\Demo;

use Magento\Framework\App\Action\Context;
use Unit4\Module6\Model\VendorFactory;


class Index extends \Magento\Framework\App\Action\Action
{

    protected $_vendorFactory;


    public function __construct(
        Context $context,
        VendorFactory $vendorFactory,
        array $data = array()
    ) {
        parent::__construct($context, $data);
        $this->_vendorFactory = $vendorFactory;
    }




    public function execute()
    {
        $vendorModel = $this->_vendorFactory->create();
        $vendorCollection = $vendorModel->getCollection();
        var_dump($vendorCollection->getData());
    }
} 

Injecting the Collection class directly in the __construct() function:

<?php

namespace Unit4\Module6\Controller\Demo;

use Magento\Framework\App\Action\Context;
use Unit4\Module6\Model\ResourceModel\Vendor\Collection;


class Index extends \Magento\Framework\App\Action\Action
{

    protected $_collection;


    public function __construct(
        Context $context,
        Collection $collection,
        array $data = array()
    ) {
        parent::__construct($context, $data);
        $this->_collection = $collection;
    }




    public function execute()
    {
        $vendorCollection = $this->_collection;
        var_dump($vendorCollection->getData());
    }
}

So what is the advantage of using Factories here?

Best Answer

Since you are foremost asking for best practice: The best practice is to create the collection using factories, getCollection() is a shortcut that I would see as a relict from Magento 1.

It's not deprecated, but if you look at the code, it becomes clear that the team is not quite happy with it but also don't really deem it important:

  • A TODO comment that sits there since 0.1.0-alpha108 (12/2014)

     * @TODO MAGETWO-23541: Incorrect dependencies between Model\AbstractModel and Data\Collection\Db from Framework
    
  • Direct use of object manager:

    return $this->_resourceCollection ? clone $this
        ->_resourceCollection : \Magento\Framework\App\ObjectManager::getInstance()
        ->create(
            $this->_collectionName
        );
    

Technically there is no big difference. Although the use of clone in getCollection() might lead to subtle differences compared to always instantiating a new object.

Full source: https://github.com/magento/magento2/blame/a45e591ab7380346eb57db291e49ac96b29dfb0a/lib/internal/Magento/Framework/Model/AbstractModel.php#L489-L519

Related Topic