PHP Yii: Aplicando ActiveRecord na sua aplicação

Veja neste artigo uma breve introdução aos conceitos de ActiveRecord e como o Yii Framework implementa estes fundamentos através da classe base CActiveRecord.

Com o passar dos anos, as linguagens de programação evoluíram, assim como as formas de modelar e desenvolver software. Novas tecnologias surgem frequentemente no cenário do desenvolvimento de software em todas as plataformas, sejam elas Windows, Unix, etc. Junto ao surgimento destas tecnologias, há também as grandes corporações, as quais estão sempre acompanhando esta evolução, transformando o desenvolvimento de aplicações em uma verdadeira corrida tecnológica.

O ActiveRecord é uma destas tecnologias de momento, uma nova forma de acessar/manipular informações do banco de dados. Esta forma de desenvolvimento é muito útil para aplicações que não possuem regras de negócio complexas, ou seja, toda a ação de persistência é feita, basicamente, através de CRUDs (create, read, update, delete).

O conceito de ActiveRecord utiliza o modelo de orientação a objetos relacional (ORM – Object Relational Mapping), onde cada entidade, ou no modelo físico tabela, é mapeada e refletida em um objeto. Portanto, cada linha (row) da tabela é ”empacotada” e associada a um objeto (wrapped). Possíveis relacionamentos entre estas tabelas são representados como atributos (propriedades) de classe. É dado o nome de tupla à cada instância de objeto.

A preocupação principal do ActiveRecord é a forma como o dado entra e qual será seu comportamento, pois a maioria dos dados irão persistir e precisarão ser gravados na base de dados.

Qualquer alteração aplicada no objeto influencia diretamente na tabela do banco de dados. Por exemplo, ao fazer um update (atualizar) dados de um objeto, seu registro no banco correspondente também é afetado. Para tratar dados resgatados do banco clara e coerentemente, o ActiveRecord utiliza o paradigma da Orientação a Objetos. No Yii Framework, a classe responsável por todo este processo de manipulação dos dados entre objeto e banco é a CActiveRecord.

No ActiveRecord a lógica de domínio e persistência dos dados são encapsuladas no mesmo local, normalmente na classe a qual estende a CActiveRecord, no caso do Yii.

Nota: Não será abordado neste texto as vantagens e desvantagens em usar o ActiveRecord, apenas sua aplicação no Yii Framework. Este assunto será tema para outro artigo. Para um bom entendimento deste texto faz-se necessário conhecimento sólido em Orientação a Objetos.

Conhecendo a CActiveRecord.

Como foi dito antes, a classe CActiveRecord é a responsável por manipular os objetos que posteriormente serão acoplados às tabelas. No Yii Framework todas as classes (models) que usarão o ActiveRecord devem estender a classe CActiveRecord.

Veja a seguir os principais métodos e atributos para criar uma aplicação corretamente com o padrão ActiveRecord. Depois será dado um exemplo prático sobre como utilizar alguns destes métodos/atributos. Para a documentação completa acesse http://www.yiiframework.com/doc/api/1.1/CActiveRecord .

Principais Atributos(propriedades) públicos.

Nota: O link a seguir explica mais profundamente o conceito de cenário, e como se aplica no Yii Framework. Acesse http://www.yiiframework.com/wiki/266/understanding-scenarios/.

Neste artigo é utilizado a versão 1.1 do Yii Framework, até então, a versão estável do framework. É possível realizar o download da versão 2, embora esta versão ainda esteja em fase beta. Acesse http://www.yiiframework.com/download/ para mais informações.

Principais métodos públicos

  • addError(string $atributo, string $erro) - Adiciona erro para um atributo.
  • attributeLabels() - Retorna os valores de label pré-definidos.
  • attributeNames() - Retorna o nome de todos os atributos.
  • count(mixed $condicao='', array $paramametros=array( )) - Retorna o número de linhas da consulta executada.
  • createValidators() - Cria objetos validadores baseado nas especificações definidas nas rules.
Nota: Para mais informações sobre rules acesse http://www.yiiframework.com/wiki/56/ .
  • delete() - Apaga determinado registro da tabela correspondente ao objeto AcriveRecord.
  • deleteAll(mixed $condicao='', array $parametros=array ( )) - Apaga todos os registros da tabela de acordo com a condição passada por parâmetro.
  • deleteAllByAttributes(array $atributos, mixed $conditicao='', array $parametros=array ( )) - Apaga todos os registros de acordo com os atributos e valores passados por parâmetro.
  • deleteByPk(mixed $chavePrimaria, mixed $condicao='', array $parametros=array ( )) - Apaga o registro a partir da chave primária (Primary Key) passada por parâmetro.
  • exists(mixed $condicao='', array $parametros=array ( )) - Verifica se a linha correspondente à condição passada existe.
  • find(mixed $condicao='', array $parametros=array ( )) - Retorna a primeira linha que conferir com a condição passada por parâmetro.
  • findAll(mixed $condicao='', array $parametros=array ( )) - Retorna todas as linhas que conferirem com a condição passada por parâmetro.
  • findAllByAttributes(array $atributos, mixed $condicao='', array $parametros=array ( )) - Retorna todas as linhas de acordo com os atributos e condição passados.
  • findAllByPk(mixed $chavePrimaria, mixed $condicao='', array $parametros=array ( )) - Retorna todos os registros de acordo com a chave primária e condição passadas.
  • getAttribute(string $nomeAtributo) – Retorna o atributo passado por parâmetro.
  • model(string $nomeClasse='CActiveRecord') – Método estático que retorna a instância da classe ActiveRecord atual.
  • save(boolean $comValidacao=true, array $atributos=NULL) – Salva os dados do objeto na tabela correspondente.
  • setAttribute(string $nome, mixed $valor) – Altera os respectivos nomes e valores de um determinado atributo.
  • update(array $atributos=NULL) – Atualiza os dados do objeto, e consequentemente da tabela.
  • updateByPk(mixed $chavePrimaria, array $atributos, mixed $condicao='', array $parametros=array ( )) - Atualiza o registro da linha passada pela chave primária.

Exemplo prático

Agora que já é sabido as principais funcionalidades da classe CactiveRecord vamos a um exemplo prático. Em outro artigo, aqui mesmo na DevMedia, foi explicado a operação de cadastrar dados no banco, diante disso, no exemplo a seguir será considerado os dados já cadastrados no banco. De forma que aqui será visto como ler e exibir estes dados na aplicação. Para mais informações acesse https://www.devmedia.com.br/php-yii-framework-trabalhando-com-banco-de-dados-na-pratica/30980 .

Cenário da aplicação

O portal de notícias fictício “PortalNews” é um grande jornal, e tem como principal foco noticias sobre esporte. Em sua página são exibidas notícias que possuem: id, autor responsável pela publicação, categoria, título e conteúdo. Toda notícia possui, obrigatoriamente uma, e somente uma categoria. Apenas usuários administradores podem publicar notícias.

Veja nas Figuras 1, 2 e 3 as tabelas de Notícia, Categoria e Administrador, respectivamente.

Figura 1. Tabela de Notícias.

Figura 2.Tabela de Categorias.


Figura 3. Tabela de Administradores.

Listando Notícias

Nota: O Yii Framework, através do Gii (gerador de models, controllers e módulos), cria por padrão as actions de index e view, onde são listados os registros(notícias) e são exibidas informações específicas de um registro(notícia), respectivamente. Para fins didáticos, neste exemplo serão ignoradas estas actions, sendo assim elas serão criadas manualmente. Actions: actionListaNoticias() e actionExibeNoticia().

Criando Action de Notícias

Agora é hora de colocar em prática algumas utilidades do ActiveRecord, para isso usaremos a função findAll() do Yii Framework. Abra o seu controlador de notícias e digite o seguinte código da Listagem 1 para criar a actionListaNoticias().

Listagem 1. Criando a action Lista Noticias.

// Resto do código omitido para melhor visualização da action criada. public function actionListaNoticias(){ $noticias = Noticia::model()->findAll(); $this->render('listaNoticias', array( 'noticias'=>$noticias, )); }

Note que o método estático model() tem a função de retornar a instância da classe, sem a necessidade de criar um novo objeto separadamente.

Depois de criada a Action é necessário configurar no controlador quais serão as restrições desta nova action criada, isto é feito através da função rules(), já citada antes. Neste caso a página de visualização de notícias será pública, isto é, visível a todos os níveis de usuário. Veja na Listagem 2 como ficará a rules() implementada com as novas regras de restrição.

Listagem 2. Acrescentando regra da action Criada.

// Código omitido para melhor visualização. public function accessRules(){ return array( //ALTERAÇÃO SERÁ FEITA AQUI, PARAMETRO “ACTIONS” array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view', 'listaNoticias'), 'users'=>array('*'), ), // FIM DA ALTERAÇÃO array('allow', // allow authenticated user to perform 'create' and 'update' actions 'actions'=>array('create','update'), 'users'=>array('@'), ), array('allow', // allow admin user to perform 'admin' and 'delete' actions 'actions'=>array('admin','delete'), 'users'=>array('admin'), ), array('deny', // deny all users 'users'=>array('*'), ), ); }

Criação da View de Notícias

A estrutura dos dados no banco está pronta, agora é hora de renderizarmos as informações advindas do banco de dados. É aí que entra o papel da view, vamos criá-las.

Acesse sua pasta views, a qual se situa em protected/views/noticia, e dentro dela crie o arquivo listaNoticias.php. Digite o código da Listagem 3 em sua view.

Listagem 3. Exibindo dados na View.

<?php for ($i=0; $i < count($noticias); $i++):?> <div> <h3> <?php echo $noticias[$i]['titulo']; ?> </h3> </div> <div> <p> <?php echo $noticias[$i]['conteudo']; ?> </p> <small> Classificado como: <?php // Dados relacionados no banco de dados ?> <?php echo $noticias[$i]->idCategoria0['nome']; ?> </small> </div> <div align="right"> <small> Postado em: <?php echo $noticias[$i]['data']; ?> </small> </div> <?php endfor; ?>

A partir deste momento, se tudo estiver ocorrido de forma correta, a sua página de Notícias será semelhante à Figura 4.

Figura 4. Página de exibição de Notícias.

Página específica de cada notícia

O “Portal News” esta quase pronto, algumas funcionalidades bastante interessantes estão funcionando bem. Entretanto, como todo bom portal de notícias, o “Portal News” também possui uma página específica para cada notícia cadastrada.

Action Exibe Noticia

Ainda no controlador Noticia, crie a actionExibeNoticia(), note que ela receberá por parâmetro o id da notícia requisitada. Confira na Listagem 4.

Listagem 4. Criando action Exibe Noticia.

// Código omitido acima para facilitar o entendimento. public function actionExibeNoticia($id){ $noticia = Noticia::model()->find('id='.$id); $this->render('exibeNoticia', array( 'noticia'=>$noticia, )); }

Não esqueça de alterar as restrições de visualização da action criada. Confira na Listagem 5.

Listagem 5. Alterando permissões da action Exibe Noticia.

public function accessRules(){ return array( // ALTERAÇÃO AQUI! array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view', 'listaNoticias', 'exibeNoticia'), 'users'=>array('*'), ), // FIM DA ALTERACAO array('allow', // allow authenticated user to perform 'create' and 'update' actions 'actions'=>array('create','update'), 'users'=>array('@'), ), array('allow', // allow admin user to perform 'admin' and 'delete' actions 'actions'=>array('admin','delete'), 'users'=>array('admin'), ), array('deny', // deny all users 'users'=>array('*'), ), ); }

View Exibe Noticia

Dentro do diretório “protected/views/noticia” crie o arquivo(view) exibeNoticia.php e preencha-o com o seguinte código da Listagem 6.

Listagem 6. Construção da View responsável por exibir a notícia.

<div> <h3> <?php echo $noticia['titulo']; ?> </h3> </div> <div> <p> <?php echo $noticia['conteudo']; ?> </p> <small> Classificado como: <?php echo $noticia->idCategoria0['nome']; ?> </small> </div> <div align="right"> <small> Postado em: <?php echo $noticia['data']; ?> </small> </div>

Se tudo ocorreu conforme o esperado, a página de exibição de notícia será semelhante à Figura 5.

Figura 5. Página da Noticia.

Neste texto foi explicado os principais conceitos de um padrão de projeto ActiveRecord, além de um exemplo prático onde este padrão foi implementado no Yii Framework. Como dito antes, o assunto ActiveRecord é demasiadamente extenso, por isso foi passada apenas uma visão superficial dele. Este tema será tratado nos próximos artigos.

Até a próxima!

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados