En créant une application dans Laravel 4 après avoir lu le livre de T.Otwell sur les bons modèles de conception dans Laravel, je me suis retrouvé à créer des référentiels pour chaque table de l'application.
J'ai fini avec la structure de table suivante:
- Étudiants: identifiant, nom
- Cours: identifiant, nom, id_enseignant
- Enseignants: identifiant, nom
- Devoirs: id, nom, course_id
- Scores (agit comme un pivot entre les étudiants et les devoirs): student_id, assignment_id, scores
J'ai des classes de référentiel avec des méthodes de recherche, de création, de mise à jour et de suppression pour toutes ces tables. Chaque référentiel a un modèle Eloquent qui interagit avec la base de données. Les relations sont définies dans le modèle selon la documentation de Laravel: http://laravel.com/docs/eloquent#relationships .
Lors de la création d'un nouveau cours, je ne fais qu'appeler la méthode create sur le référentiel de cours. Ce cours a des devoirs, donc lors de la création d'un, je souhaite également créer une entrée dans le tableau des scores pour chaque étudiant du cours. Je fais cela via le référentiel d'affectation. Cela implique que le référentiel de devoirs communique avec deux modèles Eloquent, avec le modèle Assignment et Student.
Ma question est la suivante: comme cette application augmentera probablement en taille et que plus de relations seront introduites, est-ce une bonne pratique de communiquer avec différents modèles Eloquent dans les référentiels ou devrait-on le faire en utilisant d'autres référentiels à la place (je veux dire appeler d'autres référentiels à partir du référentiel d'affectation ) ou devrait-il être fait dans les modèles Eloquent tous ensemble?
De plus, est-ce une bonne pratique d'utiliser le tableau des scores comme pivot entre les devoirs et les étudiants ou devrait-il être fait ailleurs?
$a = $this->account->getById(1)
je ne peux pas simplement enchaîner des méthodes comme$a->getActiveUsers()
. D'accord, je pourrais utiliser$a->users->...
, mais je retourne une collection Eloquent et aucun objet stdClass et je suis à nouveau lié à Eloquent. Quelle est la solution à cela? Déclarer une autre méthode dans le référentiel utilisateur comme$user->getActiveUsersByAccount($a->id);
? J'adorerais entendre comment vous résolvez cela ...Je termine un grand projet avec Laravel 4 et je devais répondre à toutes les questions que vous vous posez en ce moment. Après avoir lu tous les livres Laravel disponibles sur Leanpub, et des tonnes de googling, j'ai trouvé la structure suivante.
Alors disons que je construis une base de données de films. J'aurais au moins les classes suivantes de modèle éloquent:
Une classe de référentiel encapsulerait chaque classe Eloquent Model et serait responsable des opérations CRUD sur la base de données. Les classes du référentiel peuvent ressembler à ceci:
Chaque classe de référentiel étendrait une classe BaseRepository qui implémente l'interface suivante:
Une classe Service est utilisée pour coller plusieurs référentiels ensemble et contient la véritable «logique métier» de l'application. Les contrôleurs communiquent uniquement avec les classes de service pour les actions Créer, Mettre à jour et Supprimer.
Ainsi, lorsque je souhaite créer un nouvel enregistrement de film dans la base de données, ma classe MovieController peut avoir les méthodes suivantes:
C'est à vous de déterminer comment vous POSTEZ les données sur vos contrôleurs, mais disons que les données renvoyées par Input :: all () dans la méthode postCreate () ressemblent à ceci:
Étant donné que MovieRepository ne doit pas savoir comment créer des enregistrements Actor, Director ou Studio dans la base de données, nous utiliserons notre classe MovieService, qui pourrait ressembler à ceci:
Il nous reste donc une belle séparation judicieuse des préoccupations. Les référentiels ne connaissent que le modèle Eloquent qu'ils insèrent et récupèrent de la base de données. Les contrôleurs ne se soucient pas des référentiels, ils transmettent simplement les données qu'ils collectent auprès de l'utilisateur et les transmettent au service approprié. Le service ne se soucie pas de la manière dont les données qu'il reçoit sont enregistrées dans la base de données, il transmet simplement les données pertinentes qu'il a été fournies par le contrôleur aux référentiels appropriés.
la source
$studio->movies()->associate($movie);
).J'aime y penser en termes de ce que fait mon code et de ce dont il est responsable, plutôt que de «bien ou de mal». C'est ainsi que je dissocie mes responsabilités:
Dans cet esprit, il est logique à chaque fois d'utiliser un référentiel (que vous créiez interfaces.etc. Est un tout autre sujet). J'aime cette approche, car cela signifie que je sais exactement où aller lorsque j'ai besoin d'effectuer certains travaux.
J'ai aussi tendance à créer un référentiel de base, généralement une classe abstraite qui définit les principales valeurs par défaut - essentiellement des opérations CRUD, et chaque enfant peut simplement étendre et ajouter des méthodes si nécessaire, ou surcharger les valeurs par défaut. L'injection de votre modèle permet également à ce modèle d'être assez robuste.
la source
Considérez les référentiels comme un classeur cohérent de vos données (pas seulement vos ORM). L'idée est que vous souhaitez récupérer des données dans une API cohérente et simple à utiliser.
Si vous ne faites que Model :: all (), Model :: find (), Model :: create (), vous ne bénéficierez probablement pas beaucoup de l'abstraction d'un référentiel. D'autre part, si vous souhaitez appliquer un peu plus de logique métier à vos requêtes ou actions, vous pouvez créer un référentiel pour faciliter l'utilisation d'une API pour traiter les données.
Je pense que vous vous demandiez si un référentiel serait le meilleur moyen de traiter certaines des syntaxes les plus verbeuses requises pour connecter des modèles connexes. Selon la situation, il y a quelques choses que je peux faire:
En accrochant un nouveau modèle enfant à un modèle parent (un-un ou un-plusieurs), j'ajouterais une méthode au référentiel enfant quelque chose comme
createWithParent($attributes, $parentModelInstance)
et cela ajouterait simplement le$parentModelInstance->id
dans leparent_id
champ des attributs et appellerais create.En attachant une relation plusieurs-plusieurs, je crée en fait des fonctions sur les modèles afin de pouvoir exécuter $ instance-> attachChild ($ childInstance). Notez que cela nécessite des éléments existants des deux côtés.
En créant des modèles associés en une seule fois, je crée quelque chose que j'appelle une passerelle (cela peut être un peu différent des définitions de Fowler). Façon que je peux appeler $ gateway-> createParentAndChild ($ parentAttributes, $ childAttributes) au lieu d'un tas de logique qui peut changer ou qui compliquerait la logique que j'ai dans un contrôleur ou une commande.
la source