Magento 2 Custom Collection – Proper Implementation Guide

collection;custom-collectionmagento2module

I am trying to inject a CollectionFactory object into a Plugin like this:

/**
 * PopulateCustomerCards constructor.
 * @param CardCollectionFactory $cardCollectionFactory
 */
public function __construct(
    CardCollectionFactory $cardCollectionFactory
) {
    $this->cardCollectionFactory = $cardCollectionFactory;
}

I also create the Collection class like this:

class Collection extends Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    public function doSomething()
    {
        /* ... some magic is done here */
    }
}

When I run setup:di:compile the CardCollectionFactory is created like this:

/**
 * Factory class for @see \My\Module\Model\ResourceModel\Card\Collection
 */
class CollectionFactory
{
    /**
     * Object Manager instance
     *
     * @var \Magento\Framework\ObjectManagerInterface
     */
    protected $_objectManager = null;

    /**
     * Instance name to create
     *
     * @var string
     */
    protected $_instanceName = null;

    /**
     * Factory constructor
     *
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     * @param string $instanceName
     */
    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\My\\Module\\Model\\ResourceModel\\Card\\Collection')
    {
        $this->_objectManager = $objectManager;
        $this->_instanceName = $instanceName;
    }

    /**
     * Create class instance with specified parameters
     *
     * @param array $data
     * @return \My\Module\Model\ResourceModel\Card\Collection
     */
    public function create(array $data = array())
    {
        return $this->_objectManager->create($this->_instanceName, $data);
    }
}

The problem is when I run the code, file Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection breaks at line:

    $this->setConnection($this->getResource()->getConnection());

Because \Magento\Framework\DB\Adapter\AdapterInterface $connection = null is not being injected in the constructor.

Best Answer

Looks like the collection is not initialized properly. It should have knowledge about model and resource model. Add the following method to the custom collection class:

protected function _construct()
{
    $this->_init('My\Module\Model\Card', 'My\Module\Model\ResourceModel\Card');
}