Como implementar a coleção personalizada corretamente no Magento2?
-
13-12-2019 - |
Pergunta
Estou tentando injetar um objeto CollectionFactory em um plugin como este:
/**
* PopulateCustomerCards constructor.
* @param CardCollectionFactory $cardCollectionFactory
*/
public function __construct(
CardCollectionFactory $cardCollectionFactory
) {
$this->cardCollectionFactory = $cardCollectionFactory;
}
Eu também crio a classe Collection assim:
class Collection extends Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
public function doSomething()
{
/* ... some magic is done here */
}
}
Quando executo setup:di:compile o CardCollectionFactory é criado assim:
/**
* 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);
}
}
O problema é quando executo o código, arquivo Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
quebra na linha:
$this->setConnection($this->getResource()->getConnection());
Porque \Magento\Framework\DB\Adapter\AdapterInterface $connection = null
não está sendo injetado no construtor.
Solução
Parece que a coleção não foi inicializada corretamente.Deve ter conhecimento sobre modelo e modelo de recursos.Adicione o seguinte método à classe de coleção personalizada:
protected function _construct()
{
$this->_init('My\Module\Model\Card', 'My\Module\Model\ResourceModel\Card');
}
Outras dicas
Posso estar errado aqui, mas uma coisa que você precisa lembrar sobre as fábricas geradas automaticamente é que acho que elas só funcionam para classes onde a injeção de dependência pode fornecer todos os argumentos do construtor.Por exemplo, se você precisar criar produtos onde o construtor requer um ID de produto, a fábrica padrão não funcionará - o método create() precisa ser create($productId).
Neste caso, a classe de coleção abstrata base utiliza 'conexão' como argumento do construtor, com um valor padrão de 'nulo'.Ver https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php#L116
Estou me perguntando se o problema é que a conexão não está sendo fornecida e precisa ser fornecida, ou a configuração do di.xml por algum motivo não está fornecendo a conexão (não estou familiarizado com esse nível de código - então, apenas tentando fornecer uma dica, não é uma solução completa).
Mas é algo a ter em atenção.Parece que a conexão precisa ser fornecida, mas não é.(Outra razão possível é o tipo de argumento da coleção abstrata não corresponder ao arquivo di.xml.)