Ao criar um aplicativo no Laravel 4, depois de ler o livro de T. Otwell sobre bons padrões de design no Laravel, me vi criando repositórios para todas as tabelas do aplicativo.
Acabei com a seguinte estrutura de tabela:
- Alunos: id, nome
- Cursos: id, nome, teacher_id
- Professores: id, nome
- Tarefas: id, nome, course_id
- Pontuações (atua como um pivô entre os alunos e as tarefas): student_id, assignment_id, scores
Eu tenho classes de repositório com métodos find, create, update e delete para todas essas tabelas. Cada repositório possui um modelo Eloquent que interage com o banco de dados. Os relacionamentos são definidos no modelo de acordo com a documentação do Laravel: http://laravel.com/docs/eloquent#relationships .
Ao criar um novo curso, tudo o que faço é chamar o método create no Repositório do Curso. Esse curso tem tarefas, portanto, ao criar um, também quero criar uma entrada na tabela de pontuação para cada aluno do curso. Eu faço isso através do Repositório de Tarefas. Isso implica que o repositório de tarefas se comunica com dois modelos Eloquent, com o modelo de Tarefas e Alunos.
Minha pergunta é: como esse aplicativo provavelmente aumentará de tamanho e mais relacionamentos serão introduzidos, é uma boa prática se comunicar com diferentes modelos Eloquent em repositórios ou isso deve ser feito usando outros repositórios (quero dizer, chamar outros repositórios do repositório de atribuição ) ou deve ser feito nos modelos Eloquent todos juntos?
Além disso, é uma boa prática usar a tabela de pontuações como um pivô entre tarefas e alunos ou deve ser feita em outro lugar?
$a = $this->account->getById(1)
não posso simplesmente encadear métodos como$a->getActiveUsers()
. Ok, eu poderia usar$a->users->...
, mas retornarei uma coleção Eloquent e nenhum objeto stdClass e estou vinculado a Eloquent novamente. Qual a solução para isso? Declarando outro método no repositório do usuário como$user->getActiveUsersByAccount($a->id);
? Gostaria de saber como você resolver isso ...Estou finalizando um grande projeto usando o Laravel 4 e tive que responder a todas as perguntas que você está fazendo no momento. Depois de ler todos os livros disponíveis do Laravel no Leanpub e toneladas de Google, criei a seguinte estrutura.
Então, digamos que estou construindo um banco de dados de filmes. Eu teria pelo menos as seguintes classes do Modelo Eloquent:
Uma classe de repositório encapsularia cada classe do Modelo Eloquent e seria responsável pelas operações de CRUD no banco de dados. As classes de repositório podem ter a seguinte aparência:
Cada classe de repositório estenderia uma classe BaseRepository que implementa a seguinte interface:
Uma classe de serviço é usada para colar vários repositórios e contém a "lógica de negócios" real do aplicativo. Os controladores se comunicam apenas com as classes de serviço para as ações Criar, Atualizar e Excluir.
Portanto, quando eu quero criar um novo registro de filme no banco de dados, minha classe MovieController pode ter os seguintes métodos:
Depende de você determinar como você envia os dados para seus controladores, mas digamos que os dados retornados por Input :: all () no método postCreate () sejam algo como:
Como o MovieRepository não deve saber como criar registros de ator, diretor ou estúdio no banco de dados, usaremos nossa classe MovieService, que pode ser algo assim:
Então, o que nos resta é uma separação agradável e sensata de preocupações. Os repositórios conhecem apenas o modelo Eloquent que eles inserem e recuperam do banco de dados. Os controladores não se importam com os repositórios, apenas entregam os dados que coletam do usuário e os transmitem ao serviço apropriado. O serviço não se importa como os dados recebidos são salvos no banco de dados, apenas entrega os dados relevantes que foram fornecidos pelo controlador aos repositórios apropriados.
fonte
$studio->movies()->associate($movie);
).Eu gosto de pensar nisso em termos do que meu código está fazendo e do que é responsável, em vez de "certo ou errado". É assim que eu separo minhas responsabilidades:
Com isso em mente, faz sentido sempre usar um repositório (se você cria interfaces.etc. É um tópico totalmente diferente). Eu gosto dessa abordagem, porque significa que sei exatamente para onde ir quando precisar fazer um determinado trabalho.
Eu também tendem a criar um repositório base, geralmente uma classe abstrata que define os principais padrões - basicamente operações CRUD, e cada filho pode apenas estender e adicionar métodos conforme necessário, ou sobrecarregar os padrões. Injetar seu modelo também ajuda esse padrão a ser bastante robusto.
fonte
Pense nos Repositórios como um arquivo consistente dos seus dados (não apenas dos ORMs). A idéia é que você deseja coletar dados em uma API consistente e simples de usar.
Se você estiver apenas fazendo Model :: all (), Model :: find (), Model :: create (), provavelmente não se beneficiará muito de abstrair um repositório. Por outro lado, se você quiser fazer um pouco mais de lógica comercial em suas consultas ou ações, poderá criar um repositório para facilitar o uso da API para lidar com dados.
Eu acho que você estava perguntando se um repositório seria a melhor maneira de lidar com algumas das sintaxes mais detalhadas necessárias para conectar modelos relacionados. Dependendo da situação, há algumas coisas que posso fazer:
Pendurando um novo modelo filho de um modelo pai (um-um ou um-muitos), eu adicionaria um método ao repositório filho, algo como
createWithParent($attributes, $parentModelInstance)
isso e isso apenas adicionaria$parentModelInstance->id
oparent_id
campo de atributos e chamaria create.Anexando um relacionamento muitos-muitos, eu realmente crio funções nos modelos para poder executar $ instance-> attachChild ($ childInstance). Observe que isso requer elementos existentes nos dois lados.
Criando modelos relacionados em uma execução, crio algo que chamo de Gateway (pode ser um pouco diferente das definições de Fowler). Como posso chamar $ gateway-> createParentAndChild ($ parentAttributes, $ childAttributes) em vez de um monte de lógica que pode mudar ou complicar a lógica que tenho em um controlador ou comando.
fonte