Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

miquelarranz's avatar

Repositories design doubt

Hello guys,

I have seen some lessons where Jeffrey uses repositories and injects them on the controllers. In terms of design I don't understand why he's accessing them through the controllers instead of the models. I think that in this situation, when you need to do some logic before storing a new User, you have to do a double access to the Model Layer (just a random example). Injecting the repositories on the models wouldn't be more logical (and you only have to do one access to the Model Layer)?

I am probably wrong and saying something stupid but I would appreciate an explanation since I don't understand it.

Greeting,

Miquel

0 likes
9 replies
Penderis's avatar

I do not use "repositories" as they are probably meant to not even sure that what mine are called, I like the idea of calling them service providers, a class with methods that are action specific, i have one for creating and updating files, one for setting up form data before saving the model ect. I think of it that if i look at my controller

//it should read easy
use my/AssetCreator;
use my/FormCleaner;

public function index(){
 $generateUserPhoto = new AssetCreator();
if($generateUserPhoto->resize()){
    return Redirect::back()->with('PhotoSuccess',$generateUserPhoto->success);
    }else{
//error stuff here
    }
}

The thing is the variable names ect make your code read like a story.

Obviously he does it all fancy dependency injection like but I just have not gotten to the point of trying to understand App::make()

1 like
bobbybouwmann's avatar

The repository mediates between the data source layer and the business layers of the application. It queries the data source for the data, maps the data from the data source to a business entity, and persists changes in the business entity to the data source. A repository separates the business logic from the interactions with the underlying data source or Web service.

Simply put, repositories are abstraction layers between some type of storage and your application or business logic. Think of it as going to shelves to grab some items in one motion.

A great design pattern for Laravel projects is to add a repository abstraction layer in front of your models to perform functions such as creation, searching, deleting, etc. By example, think about making a tag basd CRM. At first you may have the tags set in a CSV list in a user model. So, using traditional Eloquent techniques you would always have to have:

$users = User::where('tags', 'like', $tag)->get();

But quickly moving over to a many-to-many relationship means that everywhere you had the above query, you would have to change over to:

$tags = Tags::with('users')->where('tag', $tag)->get();
$users = $tags->users;

Then think again of having to move this over to raw SQL queries or file storage. Instead, creating a repository gives the abstraction of making so that your controller looks like this:

$users = $this->userRepository->getWhereTag($tag);

And your repository could look like:

public function getWhereTag($tag)
{
    // Queries here
}

Hope this helps you to decide how you want to use this ;)

4 likes
RobinMalfait's avatar

A repository is responsible for "storing" objects and doing actions with it. For example a UserRepository is responsible for it's users, the UserRepository can "get" users from the db, it can store users in the db, but it can also do "special" stuff for example: give all the users that are active, via an getActiveUsers() method.

1 like
thepsion5's avatar

Another nice benefit of repositories, even if you never use them for their most obvious purpose (switching storage mediums), is that by coding to an interface (UserRepositoryInterface implemented by EloquentUserRepository, etc), it makes it very easy to add decorators to your persistence logic. This could be for audit logs, caching, event handlers, etc.

2 likes
dberry's avatar

The biggest and most important thing, is to know your application. If it calls for the Repository Pattern and interfaces, command buses, etc... then use them. Don't try to make them fit into your application though.

If you know what each of the patterns are and you understand their uses, but can't figure out how they fit into the design of your application, then they probably don't fit at all and you're just making things more complex than they need to be.

There is no sense in bringing in a back-hoe when you just needed to dig a 2'x2' hole.

1 like
miquelarranz's avatar

Thanks for your answers guys, but still need to clarify a point. I know what is a repository and I want to use the pattern mainly because I want to do the DB access functions cleaner. I think that I am not understanding what is exactly the models purpose in Laravel and that's probably why I am still confused.

I have found this image: https://bosnadev.com/wp-content/uploads/2015/03/concrete_repositories.png here https://bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5/

The business logic is responsibility of the models and I want to use the repositories like the image. I have been reading the article and when he implements it, he is accessing the repositories through the controllers instead of the models, like the image. As I said, I am still confused, because I don't know how to exactly design it.

Check this image for a more detailed schema of the pattern: https://bosnadev.com/wp-content/uploads/2015/03/repository_pattern.png maybe with this one you can explain me better what are the models on Laravel.

Thanks guys,

Miquel

MarkRedeman's avatar

@miquelarranz the purpose of the model is to simulate the real world. For instance if you take the example of a shop where you have a basket, then you might have a business rule that says that a basket can only contain 3 items. This would imply that you have the following model,

<?php

class Basket
{
    private $id;
    private $items;

    public function id()
    {
        return $this->id;
    }

    public function add(Item $item)
    {
        if (count($this->items) >= 3)
            throw new BasketIsFull;

        $this->items[] = $item;
    }

    public function items()
    {
        return $this->items;
    }
}

Of course this example is quite stupid as you probably won't have a limit to the amount of items you can have in your basket when you're visiting a webshop. However the point of the example is, is that the Basket model is responsible for validating the state of the basket (ie: there can't be more than 3 items). Your BasketRepository can then have a save() function that gets the id and the items from the basket model and then saves it to a database, however it should not be responsible for validating the state of the basket as that is something that the basket is already doing.

Also I wanted to drop this link in which Shawn McCool explains how he thinks the repository pattern should be implemented.

1 like
miquelarranz's avatar

@MarkRedeman Yes, I know the purpose of a model, but since in Laravel a model extends from Eloquent maybe it is not the same concept and it has more responsibility. And probably that's the reason why I am still a bit confused.

Please or to participate in this conversation.