Como criar Model, Resource Model e Collection no Magento 2

Lucas Teixeira dos Santos Santana - Oct 11 '21 - - Dev Community

Contextualizando

O que é ORM?

ORM (Object-Relational Mapping) é uma técnica de mapeamento de objeto-relacional que visa criar uma camada de mapeamento entre o modelo de objetos da aplicação para o modelo relacional do banco de dados, de forma a abstrair o acesso ao mesmo, ou seja, é uma técnica de mapeamento entre um modelo de dados relacional e um modelo orientado a objetos que geralmente é a biblioteca ou framework que ajuda no mapeamento e uso do banco de dados. a ORM visa resolver, ou pelo menos minimizar, as diferenças entres estes dois modelos.

A ORM é uma biblioteca que é escrita para encapsular o código necessário para manipular os dados, para que não seja necessário utilizar o SQL no código da programação orientada a objetos.

O Magento 2 não tem todos os recursos normalmente oferecidos por uma ORM, ele possui apenas uma abstração sobre consultas por linhas do SQL (Resource Model).

Quando usar as classes Model, Resource Model e Collection?

As classes de Model, Resource Model e Collection estendem classes que fazem o mapeamento entre a abstração da entidade e o modelo relacional do banco de dados.

Estas classes servem para o gerenciamento de dados em uma tabela personalizada, ou seja, as classes são para operações de dados no modelo CRUD (Create, Read, Update e Delete) de uma única tabela. Saiba como criar uma tabela personalizada no post "Como criar tabelas personalizadas no banco de dados com db_schema.xml no Magento 2".


Código para a criação da Model, Resource Model e Collection

Model

A classes Model é responsável por diversas funções, como as regras de negócio de uma aplicação, encapsular dados do seu negócio, acessar, extrair e manipular dados das entidades. O termo Model vêm do padrão de arquitetura MVC (Model-Controller-View).

A classe Model deve seguir a estrutura de pastas \{Vendor}\{Module}\Model\{ModelName} e deve estender a classe \Magento\Framework\Model\AbstractModel, que necessita que a classe a implemente o método _construct(). A classe Model herdará a classe \Magento\Framework\DataObject para seus objetos.

<?php

namespace {Vendor}\{Module}\Model;

use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Model\Context;
use Magento\Framework\Registry;
use {Vendor}\{Module}\Model\ResourceModel\{ResourceModelName};

class {ModelName} extends AbstractModel
{
    protected $_cacheTag = '{table_name}';
    protected $_eventPrefix = '{table_name}';

    public function __construct(
        Context $context,
        Registry $registry
    ) {
        parent::__construct($context, $registry);
    }

    protected function _construct(): void
    {
        $this->_init({ResourceModelName}::class);
    }
}
Enter fullscreen mode Exit fullscreen mode
  • $_cacheTag: um identificador único para uso de cache;
  • $_eventPrefix: um prefixo para eventos a serem disparados;

Caso a classe de modelo esteja tratando de uma entidade, é recomendado utilizar a seguinte interface \Magento\Framework\DataObject\IdentityInterface ou implementar uma interface personalizada da sua entidade com todos os métodos requisitados da entidade em questão.

Resource Model

A classe Resource Model é responsável pela execução de todas as operações no banco de dados, além de mapear uma entidade em uma tabela. Esta classe executa todas as operações de CRUD e é responsável pela lógica de negócio.

A classe Resource Model deve seguir a estrutura de pastas \{Vendor}\{Module}\Model\ResourceModel\{ResourceModelName} e deve estender a classe abstrata \Magento\Framework\Model\ResourceModel\Db\AbstractDb, que contém os métodos para buscar informações do banco de dados e requisita a implementação do método _construct().

<?php

namespace {Vendor}\{Module}\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use Magento\Framework\Model\ResourceModel\Db\Context;

class {ResourceModelName} extends AbstractDb
{
    public function __construct(
        Context $context
    ) {
        parent::__construct($context);
    }

    protected function _construct(): void
    {
        $this->_init('{table_name}', '{entity_column_id}');
    }
}
Enter fullscreen mode Exit fullscreen mode

Collection

A classe Collection é considerada a Resource Model que permite filtrar e buscar os dados de uma tabela de uma coleção da entidade, ou seja, uma coleção de objetos que possibilita o filtro, agrupamento, ordenação e carregamento de uma determinada entidade, array ou a própria coleção.

A classe Collection deve seguir a estrutura de pastas \{Vendor}\{Module}\Model\ResourceModel\{EntityName}\{CollectionName} e deve estender a classe abstrata \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection, que contém os métodos para tratar dos dados da coleção da entidade e requisita a implementação do método _construct(). A classe Collection instanciará a classe \Magento\Framework\Data\Collection para seus objetos de retorno da entidade.

É possível unir dados de outras tabelas em uma Collection com o join() para serem executados no banco de dados.

<?php

namespace {Vendor}\{Module}\Model\ResourceModel\{EntityName};

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Framework\Data\Collection\EntityFactoryInterface;
use Psr\Log\LoggerInterface;
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use {Vendor}\{Module}\Model\{ModelName};
use {Vendor}\{Module}\Model\ResourceModel\{ResourceModelName};

class {CollectionName} extends AbstractCollection
{
    protected $_idFieldName = '{entity_column_id}';
    protected $_eventPrefix = '{table_name}_collection';
    protected $_eventObject = '{table_name}_collection';

    public function __construct(
        EntityFactoryInterface $entityFactory,
        LoggerInterface $logger,
        FetchStrategyInterface $fetchStrategy,
        ManagerInterface $eventManager,
        AdapterInterface $connection = null,
        AbstractDb $resource = null
    ) {
        parent::__construct(
            $entityFactory,
            $logger,
            $fetchStrategy,
            $eventManager,
            $connection,
            $resource
        );
    }

    protected function _construct(): void
    {
        $this->_init(
            {ModelName}::class,
            {ResourceModelName}::class
        );
    }
}
Enter fullscreen mode Exit fullscreen mode
  • $_idFieldName: campo identificador para a coleção de itens;
  • $_eventPrefix: nome do prefixo do evento que são disparados pela Model;
  • $_eventObject: nome do parâmetro do evento.

Finalizando

Valores entre chaves ({test}) devem ser alterados na implementação do código.

Habilitando o alterações

Gera a configuração das injeções de dependência e todas as classes ausentes.

# Gera a configuração das injeções de dependência e todas as classes ausentes.
php bin/magento setup:di:compile

# Limpa o armazenamento (cache) de todos os processos do Magento
php bin/magento cache:flush
Enter fullscreen mode Exit fullscreen mode

Diretórios e Arquivos

Segue a a lista de diretórios e arquivos que devem ser criados.

- app/
  - code/
    - {Vendor}/
        - {Module}/
          - etc/
            - db_schema.xml
            - module.xml
          - Model/
            - {EntityName}.php
            - ResourceModel/
              - {EntityName}.php
              - {EntityName}/
                - Collection.php
          - registration.php
          - composer.json
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .