Support the ongoing development of Laravel.io →
Database Eloquent
Last updated 3 months ago.
0

zenry said:

Repositories

Doing it via repositories work (it's closest to the last option above), but it adds an extensive middleman every time we want to deal with the model. As in your example, the repository is straightforward when it's just find, store, update or other simple methods, but what if other controllers/repositories want to interact with the model too? As other parts of code want to keep manipulating the model, instead of just feeding them Eloquent code, we'd have to continue padding in more functionality and learn a whole new interface too (since we're no longer working with eloquent's pattern).

(This, of course, assumes other bits of code can't just stretch into Eloquent when they want to do things directly, or use the repository when it's special functionality. But then that splits the responsibility over the model.)

To be fair, this is what I'm doing right now (and yes, I just keep throwing in more functionality into the repository every time I need something new). I just feel really dirty for separating fundamentally model-related code from where the model class lives. Seeing SQL in the repositories just give me the heeby-jeebies.

Thanks for the reply!

Edit: To be clear, I completely agree that a repository is the way to go if there's general model-related stuff going on, like how to fetch common groups of them. I'm just in doubt when it comes to there being specific model code, like SQL, query building, or operations that are designed to execute on single model instances. It's as if the repository isn't just a container for model-related code, but it becomes the model.

Last updated 3 months ago.
0

Okay, after going through further research and reading, I think I'm going to settle on this solution (very similar to Kyle Noland's answer on StackOverflow and building on repositories):

  • Controllers only handle user input, period. Then they pass on the request to a Service.
  • Services handle all the complex business logic and hold the glue between multiple elements of code. They contact multiple repositories and tell them to do things.
  • Repositories act as the actual model layer. Nothing else hits the Eloquent classes; only repositories do. Whenever another class wants to deal with a model, they go here. Notable: repositories do give out Eloquent objects when invoked; by convention, even if the repository does something without Eloquent, any return values will still be one. This is just for convenience in views, not for any external manipulation - I will treat them like stdClass objects.
  • Eloquent models simply sit as convenient backends to the repositories, left untouched as a configuration file, so to speak. Since they're isolated from the rest of the codebase, if I ever want to remove Eloquent's responsibility and shift to, say, plain SQL (e.g. to optimize database queries) this can happen transparently. I could even ditch Eloquent one day and just return plain stdClass objects loaded with data from QueryBuilder.

It's a more complex solution, but I like the separation of responsibilities. I tend to work with sprawling software (usually for businesses) so I prefer manageable complexity over confusing simplicity, so for anyone else reading this, I think going with a more succinct solution might be more practical. This high level of separation makes unit testing and rapid decoupling really convenient.

It feels awkward to answer my own question, but zenry got the ball rolling and rubber duck problem solving has always treated me well!

Last updated 3 months ago.
0

Have you seen this. Works perfectly, much like the stackoverflow url you mentioned. http://www.slashnode.com/reusable-repository-design-in-laravel/

Last updated 3 months ago.
0

Sign in to participate in this thread!

LaraJobs

Your banner here too?

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

The Laravel portal for problem solving, knowledge sharing and community building.

© 2022 Laravel.io - All rights reserved.