Cursos Magento

Models, Resource Models e Collections: o papel de cada um

, , , ,

Atualizado em 14 de abril de 2020

O conceito básico dos objetos de ORM (Object Relational Mapping, ou Mapeamento de Objeto Relacional) é um tópico presente em quase todas as provas para quem quer se tornar um desenvolvedor Magento certificado.

Neste artigo abordarei os conceitos de Models, Resource Models e Collections e qual o papel de cada um deles em um módulo Magento.

Os conceitos abordados aqui são válidos tanto para Magento 1 como Magento 2. Eles também foram abordados em maior ou menor detalhe no curso de Backend para Magento 1 e no curso de criação de módulos para Magento 2.

Collections e Models são o pão com manteiga do dia a dia no desenvolvimento Magento.Allan MacGregor

O que é ORM?

ORM é uma técnica ou padrão presente na maioria dos softwares modernos para converter dados – armazenados em algum lugar – em objetos (classes), permitindo sua manipulação dentro do código de forma transparente.

Em linhas gerais, a ideia por trás disso é oferecer classes para manipular dados sem preocupar o desenvolvedor sobre onde estes dados estão e como serão persistidos.

Resource Model

O objeto Model pode conter uma Resource Model que mapeia um objeto em um ou mais registros em uma “tabela”.

“Tabela” aqui pode ser interpretada como registro em um banco de dados, mas não necessariamente uma tabela de um banco MySql.

Responsabilidade do Resource Model

Resource Models são responsáveis por:

  • Executar todas operações CRUD (Criar, Ler, Atualizar, Apagar registros). Em um Resource Model baseado em MySQL – como ocorre em quase todo Magento. Ele contém o código SQL para executar estas operações.
  • Lógica de negócios. Um Resource Model pode fazer validações dos dados, iniciar processos antes ou depois que um dado é salvo (veja artigo sobre Observers), ou realizar outras operações no banco.

Se estivéssemos salvando nossos dados em arquivos .TXT, onde cada arquivo é uma tabela, e cada linha é um registro, nosso Resource Model seria responsável por ler, gravar, apagar ou atualizar as linhas de nosso TXT. Os registros poderiam estar em um ou mais arquivos.

Para pensar…

Teoricamente, se trabalhássemos nos Adapters (usados pelos Resource Models) do Magento, poderíamos trocar o MySQL por outra base de dados de nossa preferência. O problema maior seria provavelmente a compatibilidade com outros módulos que não estendem os recursos do Magento corretamente.

Exemplo de Resource Model no Magento 2

namespace Magento\Newsletter\Model\ResourceModel;

class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
...
    /**
     * Initialize resource model. Get tablename from config
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('newsletter_subscriber', 'subscriber_id');
        $this->_subscriberLinkTable = $this->getTable('newsletter_queue_link');
        $this->connection = $this->getConnection();
    }

    /**
     * Load subscriber from DB by email
     *
     * @param string $subscriberEmail
     * @return array
     */
    public function loadByEmail($subscriberEmail)
    {
        $select = $this->connection->select()->from($this->getMainTable())->where('subscriber_email=:subscriber_email');

        $result = $this->connection->fetchRow($select, ['subscriber_email' => $subscriberEmail]);

        if (!$result) {
            return [];
        }

        return $result;
    }
}

 

Collections

Se você espera trazer vários itens de uma “tabela”, então você precisaria de um tipo especial de resource model, também conhecido como Collection.

Uma Collection é uma classe que carrega vários models e devolve (geralmente) um objeto como um array ou algo parecido.

A Collection pode ser filtrada para trazer somente registros específicos, e eventualmente traz recursos de limitação, paginação, ordenação, entre outros.

Exemplo de uso de Collection:

    /**
     * Prepare collection to be displayed in the grid
     *
     * @return $this
     */
    protected function _prepareCollection()
    {
        $attributes = $this->_catalogConfig->getProductAttributes();
        /* @var $collection \Magento\Catalog\Model\ResourceModel\Product\Collection */
        $collection = $this->_productFactory->create()->getCollection();
        $collection->setStore(
            $this->getStore()
        )->addAttributeToSelect(
            $attributes
        )->addAttributeToSelect(
            'sku'
        )->addStoreFilter()->addAttributeToFilter(
            'type_id',
            $this->_salesConfig->getAvailableProductTypes()
        )->addAttributeToSelect(
            'gift_message_available'
        );

        $this->setCollection($collection);
        return parent::_prepareCollection();
    }

 

Models

O Magento faz uso do pattern MVC, onde “M” quer dizer Model.

Models são responsáveis pelas regras de negócio de uma aplicação. Eles são responsáveis por encapsular dados do seu negócio.

Estas classes geralmente realizam operações envolvendo banco de dados (ou outro tipo de persistência), e fazem isso por meio dos Resource Models.

No Magento, os Models são localizados na pasta /Model dos módulos.

Exemplo de Model no Magento 2

namespace Magento\Newsletter\Model;

use ...

class Subscriber extends \Magento\Framework\Model\AbstractModel
{

...
    /**
     * Initialize resource model
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init(\Magento\Newsletter\Model\ResourceModel\Subscriber::class);
    }

    public function getId()
    {
        return $this->getSubscriberId();
    }

    public function setId($value)
    {
        return $this->setSubscriberId($value);
    }

    /**
     * Return customer subscription status
     *
     * @return bool
     */
    public function isSubscribed()
    {
        if ($this->getId() && $this->getStatus() == self::STATUS_SUBSCRIBED) {
            return true;
        }

        return false;
    }

    /**
     * Load subscriber data from resource model by email
     *
     * @param string $subscriberEmail
     * @return $this
     */
    public function loadByEmail($subscriberEmail)
    {
        $storeId = $this->_storeManager->getStore()->getId();
        $customerData = ['store_id' => $storeId, 'email'=> $subscriberEmail];

        /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */
        $customer = $this->customerFactory->create();
        $this->dataObjectHelper->populateWithArray(
            $customer,
            $customerData,
            \Magento\Customer\Api\Data\CustomerInterface::class
        );
        $this->addData($this->getResource()->loadByCustomerData($customer));
        return $this;
    }
}

Note que o Model faz uso do Resource Model e também contém regras de negócio.

 

Conclusão

Se você está aterrissando no Magento agora, talvez este assunto seja muito complexo e delicado, e este artigo só irá confundir ainda mais sua cabeça. 🙂

Se quiser ver mais detalhes sobre cada uma destas entidades, consulte meu Curso de criação de módulos e Desenvolvimento Backend para Magento 1. Neste link você encontrará uma aula inteira sobre Models para assistir gratuitamente. Em outras aulas falo sobre Collections, e outros assuntos.

Outros materiais também podem ser encontrados gratuitamente nos links abaixo.

Espero que tenha gostado.

Até a próxima.

 

 

Fontes e leituras adicionais:

Persistence Layer – Magento Devdocs

Beginner’s Guide to Magento – Cool Ryan

Últimos posts por Ricardo Martins (exibir todos)
Comentários

Deixe seu comentário

[fbcomments url="https://www.magenteiro.com/blog/magento-2/models-resource_models-collections/"]