8.4 - Table Objects
Tente uma, duas, três vezes e se possível tente a quarta, a quinta e quantas vezes for necessário. Só não desista nas primeiras tentativas, a persistência é amiga da conquista. Se você quer chegar onde a maioria não chega, faça o que a maioria não faz.
Bill Gates
Provê acesso para a coleção de entities/registros armazenados em uma tabela específica. Para cada tabela de um aplicativo em CakePHP devemos ter uma classe Table associada a ela que é usada para interagir com a referida tabela.
Antes de começar a usar Table Objects precisa garantir que tem configurada uma conexão com o banco de dados.
A classe Table fica em src/Model/Table.
Por convenção objetos Table devem usar uma tabela que é idêntica a versão em minúsculas do nome da Table. Exemplos:
ArticlesTable - artigos
BlogPostsTable - blog_posts
Caso queira usar um nome de tabela que não segue esta convenção deve setar seu nome no método setTable() no método initialize() da classe Table:
$this->setTable('nomeTabela');
O ORM também espera que cada tabela tenha uma chave primária e que seu nome seja 'id'. Caso queira usar uma PK com nome diferente de “id” use o método setPrimaryKey() também no initialize() da Table.
$this->setPrimaryKey('cpf');
Classes Entity usadas em classe Table.
Por default table objects usam uma classe Entity baseada na convenção de nomes. Por exemplo, se uma Table tem nome ClientesTable então a entity respectiva será chamada de Cliente, no singular, visto que liga com apenas um registro por vez. Caso precise mudar esta convenção use o método setEntityClass() no initialize da Table:
Para Cake com versão anterior a 3.4.0:
$this->entityClass('App\Model\Entity\PO');
Superior a 3.4.0:
$this->setEntityClass('App\Model\Entity\PO');
Instância de uma Table:
Antes de começar a consultar uma tabela precisamos ter uma instância da mesma. Podemos fazer isso usando a classe TableRegistry:
// Em um método de controller ou de uma table adicione a linha
use Cake\ORM\TableRegistry;
Lifecycle Callbacks/Eventos
Os eventos são úteis se você deseja conectar-se ao ORM e adicionar lógica sem subclassificar ou substituir métodos. Ouvintes de eventos podem ser definidos em Tables ou classes de Behavior. Você também pode usar o gerenciador de eventos de uma tabela para vincular os ouvintes. São semelhantes aos eventos dos controllers e componentes.
Lista de eventos
Model.initialize
Model.beforeMarshal
Model.beforeFind
Model.buildValidator
Model.buildRules
Model.beforeRules
Model.afterRules
Model.beforeSave
Model.afterSave
Model.afterSaveCommit
Model.beforeDelete
Model.afterDelete
Model.afterDeleteCommit
Alguns eventos
initialize()
Cake\ORM\Table::initialize(Event $event, ArrayObject $data, ArrayObject $options)
O evento Model.initialize é disparado após o método construtor.
beforeFind
Cake\ORM\Table::beforeFind(Event $event, Query $query, ArrayObject $options, $primary)
The Model.beforeFind event is fired before each find operation. By stopping the event and supplying a return value you can bypass the find operation entirely.
buildValidator
Cake\ORM\Table::buildValidator(Event $event, Validator $validator, $name)
O evento Model.buildValidator é disparado quando o $name validator é criado.
buildRules
Cake\ORM\Table::buildRules(Event $event, RulesChecker $rules)
O evento Model.buildRules é disparado após uma instância de rules ser criada e após o método buildRules da Table ser chamado.
beforeRules
Cake\ORM\Table::beforeRules(Event $event, EntityInterface $entity, ArrayObject $options, $operation)
O evento Model.beforeRules é disparado entes de uma entity ter a rules aplicada.
afterRules
Cake\ORM\Table::afterRules(Event $event, EntityInterface $entity, ArrayObject $options, $result, $operation)
O evento Model.afterRules é disparado após uma entity ter a rules rules aplicada.
beforeSave
Cake\ORM\Table::beforeSave(Event $event, EntityInterface $entity, ArrayObject $options)
O evento Model.beforeSave é disparado antes de cada entity ser salva.
afterSave
Cake\ORM\Table::afterSave(Event $event, EntityInterface $entity, ArrayObject $options)
O evento Model.afterSave é disparado após uma entity ser salva.
afterSaveCommit
Cake\ORM\Table::afterSaveCommit(Event $event, EntityInterface $entity, ArrayObject $options)
O evento Model.afterSaveCommit é disparado após a transação em que a operação save é embutida ser committed.
beforeDelete
Cake\ORM\Table::beforeDelete(Event $event, EntityInterface $entity, ArrayObject $options)
O evento Model.beforeDelete é disparado antes que uma entity seja deletada.
afterDelete
Cake\ORM\Table::afterDelete(Event $event, EntityInterface $entity, ArrayObject $options)
O evento Model.afterDelete é disparado após uma entity ser deletada.
afterDeleteCommit
Cake\ORM\Table::afterDeleteCommit(Event $event, EntityInterface $entity, ArrayObject $options)
O evento Model.afterDeleteCommit é disparado após a transação em que a operação delete está embutida for committed.
Prioridades nos callbacks
Ao usar eventos em suas Tables e Behaviors, esteja ciente da prioridade a que os ouvintes de pedidos estão conectados. Eventos de Behaviors são anexados antes dos eventos da Tabela. Com as prioridades padrão, isso significa que retornos de chamada de Behavior são acionados antes do evento de Table com o mesmo nome.
Por exemplo, se sua tabela estiver usando TreeBehavior, o método TreeBehavior::beforeDelete() será chamado antes do método beforeDelete() da sua Table, e você não poderá trabalhar com os nós filhos do registro que estão sendo excluídos no método da sua Table.
Podemos gerenciar eventos de prioridades de uma das duas maneiras:
Mude a prioridade de Behavior listeners usando a opção priority. Isto irá modificar a prioridade de todos os métodos callback no Behavior:
// In a Table initialize() method
$this->addBehavior('Tree', [
// Default value is 10 and listeners are dispatched from the
// lowest to highest priority.
'priority' => 2,
]);
Modifique a prioridade em sua classe Table usando o método Model.implementedEvents(). Isso permite que você atribua uma prioridade diferente por método callback:
// In a Table class.
public function implementedEvents()
{
$events = parent::implementedEvents();
$events['Model.beforeDelete'] = [
'callable' => 'beforeDelete',
'priority' => 3
];
return $events;
}
Sistema de Eventos
Criar aplicativos manuteníveis é uma ciência e uma arte. É bem conhecido que uma chave para ter um código de boa qualidade é tornar seus objetos fracamente acoplados e fortemente coesos ao mesmo tempo. Coesão significa que todos os métodos e propriedades de uma classe estão fortemente relacionados à própria classe e não está tentando fazer o trabalho que outros objetos deveriam estar fazendo, enquanto o acoplamento frouxo é a medida de quão pequena uma classe é conectada a objetos externos. e quanto essa classe depende deles.
Mais detalhes em:
https://book.cakephp.org/3.0/en/core-libraries/events.html
https://book.cakephp.org/3.0/en/orm/table-objects.html
Comments fornecido por CComment