Ao inserir ou atualizar um registro, geralmente precisamos verificar ser o valor está de acordo com certas regras. Isso é especialmente importante nos casos em que os valores das colunas são informados pelos usuários. No geral, é bom nunca confiar em nenhum dado vindo do lado do cliente (usuário).
O AR efetua a validação automaticamente quando o método save() é executado. A validação é baseada em regras especificadas pelo método rules() da classe AR. Para mais detalhes sobre como especificar regras de validação consulte Declarando Regras de Validação. Abaixo temos o fluxo típico necessário para salvar um registro:
Quando os dados para inserção ou atualização são enviados pelos usuários através de um formulário HTML, precisamos atribuí-los as propriedades correspondentes da classe AR. Podemos fazer isso da seguinte maneira:
Se existirem muitos campos, teríamos uma longa lista dessas atribuições. Esse trabalho pode ser aliviado, por meio da propriedade attributes, como feito no exemplo abaixo. Mais detalhes podem ser consultados em Atribuição de Atributos Seguros e Criando uma Ação.
Assim como registros de uma tabela, as instâncias AR também são unicamente identificadas pelos valores de suas chaves primárias. Portanto, para comparar duas instâncias AR, precisamos apenas comparar os valores de suas chaves, assumindo que ambas pertencem a mesma classe. Entretanto, existe uma maneira mais simples de compara-las, que é utilizar o método CActiveRecord::equals().
Informação: Diferente das implementações de Active Record em outros frameworks, o Yii suporta chaves primárias compostas em seu AR. Uma chave primária composta é formada por duas ou mais colunas. De forma correspondente, a chave primária é representada por um vetor no Yii. A propriedade primaryKey retorna a chave uma instância AR.
A classe CActiveRecord possui alguns métodos que podem ser sobrescritos por suas classes derivadas, para personalizar seu fluxo de funcionamento.
beforeValidate e afterValidate: esses métodos são executados antes e depois que uma validação é executada
beforeDelete e afterDelete: esses métodos são executados antes e depois que uma instância AR é excluída.
beforeFind: esse método é chamado antes que um objeto AR finder seja utilizado para executar uma consulta (por exemplo, find(), findAll()). Ele está disponível a partir da versão 1.0.9.
Todas as instâncias AR contém uma propriedade chamada dbConnection que é uma instância da classe CDbConnection. Podemos então, utilizar o recurso de transações existente no DAO do Yii para trabalhar com Active Record.
Nota: O suporte a named scopes está disponível a partir da versão 1.0.5. A idéia original dos named scopes veio do Ruby on Rails.
Um named scope representa um critério de consulta com um nome, que pode ser combinado com outros named scopes e ser aplicado em uma consulta com active record.
Named scopes são declarados, normalmente, dentro do método CActiveRecord::scopes(), como pares nome-critério. O código a seguir, declara dois named scopes, published e recently, dentro da classe Post:
Cada named scope é declarado como um vetor que pode ser utilizado para iniciar uma instância da classe CDbCriteria. Por exemplo, o named scope recently especifica que o valor da propriedade order seja createTime DESC e o da propriedade limit seja 5, que será traduzido em um critério de consulta que retornará os 5 posts mais recentes.
Na maioria das vezes, named scopes são utilizados como modificadores nas chamadas aos métodos find. Vários named scopes podem ser encadeados para gerar um conjunto de resultados mais restrito. Por exemplo, para encontrar os posts publicados recentemente, podemos fazer como no código abaixo:
Geralmente, os named scopes aparecem a esquerda da chamada ao método find. Então, cada um deles fornece um critério de pesquisa que é combinado com outros critérios, incluindo o que é passado para o método find. Esse encadeamento é como adicionar uma lista de filtros em um consulta.
A partir da versão 1.0.6, named scopes também podem ser utilizados com os métodos update e delete. Por exemplo, no código a seguir vemos como deletar todos os posts publicados recentemente:
Nota: Named scopes podem ser utilizados somente como métodos a nível de classe. Por esse motivo, o método deve ser executando utilizando NomeDaClasse::model().