Sure you should. Unless you are developing a small app. Use and contribute https://github.com/rinvex/repository
It's a nice package
Cheers
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hi,
I started my project by following the "best practices" so I decided to use the Repository Design Pattern. But the problem is that I see my code become increasingly complicated, especially with relationships between models...
I have to make things like this on my controllers:
$restaurant = $restaurantRepo->find($restaurantID);
$member = $restaurantRepo->findRestaurantMember($restaurant, $memberID);
//without this repo it was smthg like this Restaurant::find($restaurantID)->members()->find($memberID);
I wonder if I was right to choose to use the Design Pattern? Maybe it was better something simpler like ModeFinder (https://laracasts.com/series/whatcha-working-on/episodes/3)
What's your opinion ? Do you use this D.P ?
PS: I use also Decorator
Sure you should. Unless you are developing a small app. Use and contribute https://github.com/rinvex/repository
It's a nice package
Cheers
The repository pattern is overrated.
If you get a clear benefit from using it, that's fine. It is appropriate in some circumstances.
But most likely you're doing it because it's "best practice". That's a bad reason.
I don't see what's wrong with Restaurant::find($restaurantID)->members()->find($memberID);
The repository pattern is overrated.
Yes. Like every pattern, code your app without it and use it only if it is absolutely required.
@EmilMoe nothing is wrong but I have to use Repository method instead of Eloquent...
Sorry but I don't agree with you guys, if you want to have a clear code and not put all your logic on the controller/model you have to separate it. You can choose to separate by your conventions or follow some "standards"
@drilon in your code above you just put an useless layer on the top of eloquent calls, it is useless and messier.
My example (your code) isn't adding anything to the model @drilon. That's why I don't understand the complexity. I myself tried to follow some guidelines for repositories, but I eventually deleted everything as it didn't help me a bit.
I have these topics for my models:
Traits and attributes
Overrides
Get & Set
Relations
Helpers
Everything that goes into the first 4 categories are fine in the model, helpers, if there are too many, should be moved to somewhere else. Sometimes it's a package, sometimes it's what you can call a repository, I tend to just call it a supporting class. This supporting class usually extends the model, so it's just a way of separating it, and then I instantiate the supporting class from there on.
Sorry but I don't agree with you guys, if you want to have a clear code and not put all your logic on the controller/model you have to separate it.
You can still separate code into multiple classes without using the repository pattern. For example, you can use a trait.
You can choose to separate by your conventions or follow some "standards"
Fine, but where do you stop?
Today it's the repository pattern. Tomorrow you read some more about "best practice" and learn that you should be using hexagonal architecture to properly separate the different layers of your application.
So you implement hexagonal architecture. Now you have a very "pure" architecture, so individual classes will be simple and maintainable and you are following SOLID principles. But the system has become complex and confusing.
Is that a good trade-off? In a few cases, yes; but for most projects, no.
Keep it simple. Add architecture when you have a real need for it, not because someone told you it's "best practice".
Yeah it's the: Don't code for the future, but prepare for refactor.
Do what it takes to make the app working now, but keep a minimum of organising so you can refactor in the future. Every feature will require refactoring.
Of course, I will not use something because someone told me it's "best practice", but at the begining I saw my controller or my model became very big and my code was a MESS! And I was looking on Laracasts lessons (before the whip-monstrous-code-into-shape series) how to organize better etc..
I saw a lot of open source project based on Laravel that use the Repository pattern but I think my project is more complexe and I have more relationships. That's why I am lost
My best advice again is to try to separate logic out to some packages, so your app becomes smaller but with supporting packages. This tool is great for helping making them jeroen-g/laravel-packager
Of course, I will not use something because someone told me it's "best practice", but at the begining I saw my controller or my model became very big and my code was a MESS!
Okay, that's a good starting point. :) You have a real problem that is bugging you now.
There are lots of ways you can try simplifying your code. The "Whip Monstrous Code into Shape" series is a great reference.
If the repository pattern helps you, then use it. But it sounds like you're not really happy with the results, so maybe try other options. For example, look at using service classes to get logic out of the controller, or even the model.
@EmilMoe thanx for this tip, I'll check :)
@MikeHopley what do you mean by service classes? Do you have some reference?
Service classes are a pretty general pattern.
For example, you might have a UserService class that handles some logic to do with registering users or other user-related tasks. Then in your controller you have something like this:
public function postCreateUser(UserService $service, Request $request)
{
$service->registerUser($request);
return redirect('/welcome');
}
Alternatively, you could call the service class via your User model:
// User.php model
public static function create(Request $request)
{
UserService::registerUser($request);
}
// Controller
public function postCreateUser(Request $request)
{
User::create($request);
return redirect('/welcome');
}
There are plenty of options to choose from. Look for something that makes sense to you or your team. Look for something that is straightforward and easy to read.
(I'm leaving aside the issue of validation. Again, you have various options here.)
Can we just see the code of your messy controllers?
@pmall they are no more messy: now you can find things like this:
$restaurant = $restaurantRepo->find($restaurantID);
$member = $restaurantRepo->findRestaurantMember($restaurant, $memberID);
$address = $memberRepo->findMemberAddress($member);
but the problem is that I have to think about every single case... (with pagination, with eager loading etc...) example:
$restaurant = $restaurantRepo->find($restaurantID);
$members = $restaurantRepo->getRestaurantMembers($restaurant); // this give me all
$members = $restaurantRepo->getRestaurantMembersWithPagination($restaurant, 50); // this give me 50 per page
$members = $restaurantRepo->getRestaurantMembersWithRelations($restaurant, ['address']); // this give me all members with their address
... This is the disatvantage :/
I find that messy :-)
With your choice of methods, I would do this:
return $memberRepo->findMemberAddress(
$restaurantRepo->findRestaurantMember(
$restaurantRepo->find($restaurantID),
$memberID
)
);
Cannot make thing like this because I need these on the view... (I choosed to post a simple example to make thing easier here on forum but on my app it's a little bit more complicated)
In my own opinion I think your attempt to repository is making your code seem more complex than needed, but I'm not saying it's wrong.
This :
$restaurant = $restaurantRepo->find($restaurantID);
$member = $restaurantRepo->findRestaurantMember($restaurant, $memberID);
$address = $memberRepo->findMemberAddress($member);
return view('some.view', ['restaurant' => $restaurant, 'member' => $member, 'address' => $address]);
Is at least as messier as :
$restaurant = Restaurant::find($restaurantID);
$member = $restaurant->members()->find($memberID);
$address = $member->address;
return view('some.view', ['restaurant' => $restaurant, 'member' => $member, 'address' => $address]);
but the problem is that I have to think about every single case...
Yes this is the problem with the repository pattern. Also you have to retrieve all the relationships in the controller action and send them to the view (like address above). I would just do :
$restaurant = Restaurant::find($restaurantID);
$member = $restaurant->members()->find($memberID);
return view('some.view', ['restaurant' => $restaurant, 'member' => $member]);
And use $member->address in the view.
I speak from experience : the repository pattern is disappointing.
There is also the silly long method names :-)
So you think it's better without it? At least if we don't plan to use another ORM ..?
At least if we don't plan to use another ORM
Do you really think you'll ever use another ORM ?
Try to do without it first, eloquent is very cool to use out of the box. Repositories make me feel you loose eloquent flexibility.
Since you like repository patterns, I just found this https://github.com/rinvex/repository/
Repositories seem to be a controversial topic in the Laravel community. A lot of people seem to take extreme positions on either side and either say "never use them" or "always use them".
Repositories don't have to be an all or nothing kind of thing.
I tend to put complex queries or ones that are used in multiple places in a separate class rather than in the controller or as a method on the model class itself but I don't feel the need to make sure every database interaction is in that class. For example if you are just pulling a single record by its primary key there is no difference in your controller using Model::find($id) or $repository->find($id) so I would just use eloquent directly and not bother adding that method to the repository. I also use methods like create, update, and save all the time without using a repository.
Most of the methods in my repositories tend to be queries that return lists of things or include a lot of relationship data. No reason to add the simple stuff.
Even when using a repository take advantage of of eloquent features such as eager loading and query scopes. Also don't feel the need to limit repositories from only affecting a single model. If you need a list of users and want some of the relationship data with it rather than pulling the data separately from different repositories from each table just add the query to the user repository and use eager loading to pull the other data.
Also if you are creating an interface for each repository I recommend completely dumping that approach as I don't think it provides you with a single worthwhile benefit and adds considerable extra work.
Sorry to reopen this topic, but I've forgot to ask a question. :P If we choose to not use the Repo pattern and after some time, we need to implement some Cache... All my controllers will be full of =>
Cache::remember(...,function(){
return $query......;
});
Or do you have some other technics?
PS: Should I presume that the repository Pattern take advantage only when it's used with Decorator?
You could use model events to trigger caching. But in all honesty if your database is local and your performing effiecent queries most cases cacheing doesn't help much.
I say effiecent as only selecting the data you need. Not just * (get()) but select() and get(['column']) etc.
You should check out the query object pattern. What I like to do is use Eloquent directly in my controller for simple queries like $post->find($id); then create query objects for more advanced ones.
Also have a read of this post about active record and repositories.
Please or to participate in this conversation.