Home » Code » Creating flexible Controllers in Laravel 4 using Repositories

Creating flexible Controllers in Laravel 4 using Repositories

Posted by on July 8th, 2013

Creating flexible Controllers in Laravel 4 using Repositories
Last week I looked at setting up your first Controller in Laravel 4. Controllers are what dictate how data is transferred between your Models and Views and vice versa. We set up our first RESTful controller and I described what each of the methods should be used for.

This week’s tutorial is all about creating Controllers that are flexible. Your Controllers are going to be one of the key components of your application and so you need to ensure that you build them so that if future circumstances change you don’t have to completely rewrite them.

To make the Controllers flexible, I’m going to use Repositories to abstract the database layer away.

This might seem a little bit confusing, but stick with me, it will all make sense by the end of this post.

An illustration of the problem

So to really understand what I’m trying to achieve here, first I’ll give you an example of the situation I’m trying to avoid.

For example, we have the following index method in the UserController.php file:

/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
  // Return all Users
  return User::all();
}

This method simply returns a list of all users from out application.

However, there is a problem with this:

It’s not flexibleUser::all() is tied to Laravel’s Eloquent ORM. What would you do if you needed to switch databases to use Redis or Mongo instead? Well, you would have to find all of the instances that you used Eloquent in your application and update them. This isn’t very flexible in a larger application.

This might not seem like big problem, but trust me it is! You might be thinking, “hey, as long as it works, it’s all good right?”. Well building a solid application foundation is really not that hard and Laravel makes it really easy to solve both of these problems. There’s no need to tightly couple your application to one particular ORM or database if you don’t have to. You should seize any opportunity to build future flexibility into your application!

Flexibility through Repositories

In order to cleanly separate our Controllers from the database, we are going to abstract that interaction into repositories. A repository is simply an interface between two things.

So instead of referencing Eloquent directly, we can reference UserRepository. We can then bind UserRepository to EloquentUserRepository so that Laravel knows that whenever we mention UserRepository we want an instance of EloquentUserRepository.

Now that we have abstracted the database layer into repositories it makes it much easier to switch database ORM.

For example, if you wanted to use Mongo instead, you would simply create a MongoUserRepository and bind UserRepository to it rather than EloquentUserRepository.

Now whenever Laravel wants a UserRepository it will return MongoUserRepository.

This means that you don’t have to change any of the code in your Controllers!

What are Repositories?

As I mentioned above, Repositories are simply an interface between two things. You can think of them as a contract that states that certain methods will be made available when using this interface.

For example:

You might have the following UserRepository:

interface UserRepository {

  public function all(){}

  public function find(){}

}

And the following EloquentUserRepository

class EloquentUserRepository implements UserRepository {

  public function all()
  {
    return User::all();
  }

  public function find($id)
  {
    return User::find($id);
  }

}

The UserRepository is just an interface for the EloquentUserRepository it doesn’t care what method of storing data is used, all it cares about is that those methods are available.

Now in your Controller you can use the UserRepository interface as an abstraction from the database layer.

So hopefully that all makes sense to you. We are basically just making ORM specific classes and then using an interface in the Controller as a way of talking to the database. The interface is simply the connection between the Controller and the Repository.

What do we need to build?

In order for our application to use Repositories, first we need to set things up.

We are going to need:

  • UserRepository
  • EloquentUserRepository
  • A way to bind UserRepository and EloquentUserRepository

If you remember back to building your first Laravel package, we can use Service Providers to bind things together. Service Providers are just like bootstrap classes that allow you to set things up in a certain way.

Project structure

As with a lot of things, you can get away with placing any of these things in a lot of random areas in your project. However, it’s pretty bad practice to just dump stuff in a random file or leave things in the wrong directory. As your project gets bigger, things will become a mess and everything will be unmaintainable.

Instead, I’m going to create a new directory called app/lib to store all of this kind of stuff.

In order for this directory to be included in the autoload, you also need to add it to your composer.json file.

In the classmap array, add your new directory:

"autoload": {
  "classmap": [
    // --
    "app/lib"
  ]
}

Run the following command in Terminal to update your autoload classmap:

$ composer dump-autoload

Next, in the app/lib directory, I’m going to create another directory call Cribbb to keep all of the Cribbb specific things together.

Next, I’m going to create another directory under app/lib/Cribbb called Storage to keep all of my database repositories together. And finally, I’m going to separate each resource into its own directory.

So my final directory structure is: app/lib/Cribbb/Storage/User.

Creating the User Repository

The first thing to create is the UserRepository.php interface.

<?php namespace Cribbb\Storage\User;

interface UserRepository {
  
  public function all();

  public function find($id);

  public function create($input);

}

Interfaces are extremely simple because all I’m doing here is declaring that these methods should be made available. In a future tutorial I will add the other methods I’m going to need to for updating or deleting, but for now we’ll keep it simple.

Creating the Eloquent User Repository

Next I will create the EloquentUserRepository.php file. Remember, this is simply an abstraction from the database that implements UserRepository:

<?php namespace Cribbb\Storage\User;

use User;

class EloquentUserRepository implements UserRepository {

  public function all()
  {
    return User::all();
  }

  public function find($id)
  {
    return User::find($id);
  }

  public function create($input)
  {
    return User::create($input);
  }

}

Creating the Service Provider

Next I need to create the Service Provider which will bind the two repositories together.

In app/lib/cribbb/storage create a new file called StorageServiceProvider.php, and copy the following code:

<?php namespace Cribbb\Storage;

use Illuminate\Support\ServiceProvider;

class StorageServiceProvider extends ServiceProvider {

  public function register()
  {
    $this->app->bind(
      'Cribbb\Storage\User\UserRepository',
      'Cribbb\Storage\User\EloquentUserRepository'
    );
  }

}

If you remember back to my article on creating a Laravel 4 Package, the register method is automatically called on the Service Provider. This allows you to bootstrap your files so everything is loaded correctly.

In this example, I’m binding the User Repository to the Eloquent User Repository. This means, whenever I want to use the User Repository, Laravel will automatically know that I want to use the Eloquent User Repository. If in the future I wanted to use Mongo instead, I would simply have to create a Mongo User Repository and update this binding.

Finally you need to make Laravel aware of this Service Provider by placing it in the providers array under app/config/app.php:

'providers' => array(
  // --
  'Cribbb\Storage\StorageServiceProvider'
),

Implementing the Repository in the Controller

Now we can start using the Repository in the User Controller. Open up UserController.php and add the use line to the top of your file:

<?php

use Cribbb\Storage\User\UserRepository as User;

class UserController extends BaseController {}

Next you need to create a __construct method that injects an instance of the User Repository into the Controller and sets it to the $this->user property:

public function __construct(User $user)
{
  $this->user = $user;
}

And finally, you can set the index method to return all of the users:

/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
  return $this->user->all();
}

Setting up a route and testing in the browser

Now all we need to do to ensure that everything is working correctly is to set up a route to hit so we can see what is being returned in the browser.

Open up your routes.php file and copy the following to define a new route to the User Controller:

Route::resource('user', 'UserController');

Now if you fire up the server and hit /user in your browser, you should see a JSON array displayed on the screen (as long as you actually have users in your database!).

Switching Repositories

Now if you ever need to switch ORM or database in the future, all you have to do is to create a new database Repository and update the bindings in your Service Provider.

For example, to switch to Mongo, all you would have to do is to copy the EloquentUserRepository.php and create MongoUserRepository.php. You would then replace the Eloquent code with Mongo code so that the same data is returned.

In your Service Provider, you would simply update the binding to use the Mongo repository instead of the Eloquent repository:

$this->app->bind(
  'Cribbb\Storage\User\UserRepository',
  'Cribbb\Storage\User\MongoUserRepository'
);

Now you have completely switched databases without having to change any of your Controller code!

Conclusion

Repositories allow you to create a flexible abstraction layer between your database and your Controller. Doing this enables you to separate those concerns and it prevents your Controllers being too tightly coupled with your Database.

Your Controllers don’t care what storage facility you are using to persist data, and so by using Repositories, you are able to make a clean abstraction.

This makes it beautifully simple to switch database types at some point in the future.

Next week I’m going to look at how you should structure your Controllers to make them easier to test. Again this is because your Controllers should only be concerned with their job and not what the database is doing.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

To view a full listing of the tutorials in this series, click here.

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

  • “What would you do if you needed to switch databases to use Redis or Mongo instead”

    Fancy design patterns won’t help you from making poor engineering decisions.

  • Adam Wathan

    Great article, I do have some questions though. I’ve been thinking about this subject the last few weeks and am wondering if it would truly be as simple as switching out an EloquentRepository with a RedisRepository…

    The problem I see is that the controller is expecting to get a User object, and the User class extends Eloquent. If you swap out the repository for a RedisRepository, the controller is still expecting a User object that extends Eloquent, so removing the coupling is not as simple as just swapping out the repository. I feel like you would have to have another User class that was standalone, and in the EloquentRepository you would have to create EloquentUsers and use the attributes on those models to fill the attributes on the regular User class that isn’t coupled to the ORM.

    Also, assuming you would move the “save” method to the repository and off of the object (since we’re sort of doing a Data Mapper thing here instead of Active Record), how would you handle inserting related models using the repository?

    Genuinely curious on your thoughts, this has been bugging me for a while! Enjoyed your other Laravel articles as well, looking forward to reading more.

    • Hi Adam, yes absolutely you’re right in saying that you would also have to change your models as well. That would be the part where you would be replacing your ORM.

      And yes you are correct in thinking that you would need to move the “save” method. In an upcoming tutorial I continue to build out the create and update methods, so hopefully that will show you how I would approach it.

      I think perhaps I’ve over simplified the theory of switching stuff out. I do think think that thinking about these sorts of design patterns when building stuff like this has a lot of value.

    • No, it’s not as easy as swapping out your interface. There are a LOT of design decisions that need to be made when

      1) Choosing a data store

      2) Migrating from one data store to another.

      MySQL and Redis and MongoDB and Riak and Whatever™ are not interchangeable tools. The only reasonable hot-swappable data stores would probably be postgres and maybe something like SQLServer or something.

      Redis isn’t the same sort of store (ephemeral, key/value) as Mongo (schemaless, map-reduce) as MySQL (relational). There are certainly times when you realize that you’ve chosen the wrong tool for the job, and need to migrate to something else (we’re in the process of this right now).

      The reality is, it’s taken us weeks of man power to move something in MongoDB to something else, and the reason isn’t that we don’t have the man power or we didn’t follow this repository pattern.

      The reason is that these tools are work fundamentally differently. The amount of code that has to be change to work with a different data model is just astounding.

      The way these migrations typically work in a production environment is as follows:

      1) Realize that you’re using the wrong tool
      2) Design a better system
      3) Implement the better system
      4) Allow the better system to run along side of the incorrect/bad/slow system
      5) Make sure you’re getting what you need out of the new system
      6) Repeat 2-5 several times
      7) Turn off legacy system
      8) Spend days or weeks tediously migrating legacy data to new system.

      Edit: Don’t get me wrong and think I’m advocating tightly coupling your data and your DAL, but, proper planning will probably available most use cases for this.

      • Yes! That was a much better answer than I gave! Thanks Zack! :)

        I’m going through the pain of switching one schema to another on a live database at the minute, which is a pain in of itself (MySQL -> MySQL). I would hate to have to actually move from one type of a database to another.

        You’re right, I probably shouldn’t have over simplified the benefits of this very simple pattern.

        Thanks Zack, good luck with the migration, sounds nasty!

    • George Robinson

      Thank you! I don’t understand why people are advocating using the repository pattern as the end to “tight coupling”. Whether you use the repository pattern or not, as long as your models, or entities extend Eloquent, you’re code will always be tightly coupled to Eloquent.

      • Absolutely! I think people get a bit caught up in design patterns being the perfect solution to every problem, when they are clearly not :)

  • harinder

    if its a home controller where lots of models (7-8) needs to be displayed, then i would have to inject 7-8 dependencies in controller constructr….like

    http://paste.laravel.com/AdB

    am i doing it wrong

  • vohof

    tests?

  • Ok, so using repositories to switch from Mysql to Redis/Mongo isn’t really a valid example – can someone give one (or more) good reasons to implement repositories as described above?

    • flackjap

      You can also easily mock your controllers if you ever need to test them.

    • If you know longer want to use Laravel’s ORM. Composer makes it really easy to switch out packages from the PHP community. Or if you wanted to switch to use PostgreSQL.

      Using interfaces is a really good design pattern for engineering. If you take anything away from this tutorial, let that be it, rather than as, Zack mentioned, the rather more complex situation of actually moving to a completely different type of database.

      • Alfred Nutile

        I do not know the name of the design pattern but could you not also have a class that formats the return value from the database so no matter what database returns the controllers gets the same format?
        So the controller still talks to the Repository but the repository talks to the say “Factory” class to format the return value from the database.

  • Very much like the tutorial. Helped me understand some of the things I’ve been missing with TDD.

  • Mike Beech

    Nice article, thanks.

    One question, in your example, are you still required to have a User class in the models folder that extends Eloquent?

    That’s the only way I could get it working but I felt that it kind of defeated the object of abstraction—unless I missed something of course.

    • Thanks Mike,

      Yeah that’s right, your Model should extend Eloquent.

      If you were to decide to use a different ORM, you would have to change where your Model extended from.

      • Mike Beech

        Ah cool, I didn’t miss anything then. One more Q: Is it beneficiary to abstract away the model too so that it doesn’t rely on an ORM?

        Or is the idea to extend Eloquent but not to have any specific ORM code in there, so it’ll remain easy to swap it out?

        • Hmm, I’m not sure I know what you mean.

          If you wanted to change ORM, you could simply create a new class to bind UserRespository.php to. That is the abstraction.

          • George Robinson

            The problem is, if you change to MongoDB, (which is not compatible with Eloquent) you have to override all of your relationships defined on your model, the save method, create method, destroy method and many more.

          • Yep :) Although if you were really going to migrate to using Mongo, you would probably have even bigger headaches to deal with haha :p

          • George Robinson

            That, of course! In my opinion, the best thing about using Repositories in Laravel is that you an hide your Eloquent queries from your controller, particularly queryScopes and unit test your controllers and views – which is really important.

          • Yeah, exactly. I think a lot of developers will be new to the concept of a design pattern. However, just like with almost every other design pattern in programming, there’s always going to be misinterpretations. I think being aware of the repository pattern is overall a good thing :)

  • Mat

    Wondering if someone can help

    I seem to have messed up something as I am getting the following error:

    Class ‘CribbbStorageStorageServiceProvider’ not found

    Anyone know where I can look to try to find where I screwed up?

    Thanks

    • mat

      Sorry, nevermind I found it. Apologies.

      Thanks again for the great tutorials!!

      • Glad you got it sorted!

        Often you just need to run compser dump-autoload if a class can’t be found but you know its there.

        • mat

          Thanks, yeah that was exactly the issue.

          A newb question (trying to understand what’s going on): when you say “use User;” in EloquentUserRepository.php, is that referring to the User.php model?

          • Yeah that’s exactly right! It’s just exactly the same as if you were to say return User::all(); in your Controller.

            And you have to say use because it is in a different namespace.

      • Cheanj Baldado Valdez

        hi How did you solved this problem. I also encounter this, I don’t where did I go wrong. I run composer dump-autoload but still i got the same error

        Symfony Component Debug Exception FatalErrorException (E_ERROR)

        Class ‘CareerStorageStorageServiceProvider’ not found

        Thank you for the response

        • I would comment out the service provider line, run php artisan dump-autoload, uncomment the service provider line, then run php artisan dump-autoload again.

          That normally fixes it for me.

  • Kobayakawa

    Why not store them in app/repositories ?

  • sirEllington

    And suddenly I see! Hello Interfaces!

    • Haha, I love the moment when it all comes together, glad it helped :)

  • Kana

    I’m experimenting with the use of repositories and I’m having trouble with 1 thing, for which I hope you have an answer for me.

    I have a repo that deals with storing tags. The tags table stores the tag and the tablename for which it relates too.

    Now I wonder how I can get the table name of a model to be passed into the repository when I pass in the repo into the controller.

    One way to get around this is to make a model and a repo for each tag-relationship but that sounds like overkill since every each tag-repo would do the same thing.

    How would you do this?

    • Hi Kana, I would have a look at creating a polymorphic relationship for you tags.

      For example…

      Say you have a Post model, a Picture model and a Note model. Each of these types of model can have comments associated.

      You would then create a Tag model that has a polymorphic relationship to each of these models.

      Then you could access the tags via $post->tags(); or $picture->tags(); or $note->tags();.

      Take a look at this post where I talk more about polymorphic relationships http://culttt.com/2013/06/10/laravel-4-eloquent-model-relationships/.

      Hope that helps :)

  • Huzzi

    Best Laravel tutorials I’ve come across so far. Keep up the good work.

  • Max13

    Hello !
    Great article(s), i’m discovering “frameworks” because I’ve never used them until someone told me about Laravel (The creator of Packalyst actually).

    Anyway, he gave me your website, and I’m following the articles from the first one since 1 week, really easy to understand. BUT… Sometimes it’s easy to be confused between Interface, Models, Binds… For example, in UserRepository.php you write an interface. In EloquentUserRepository.php you extends UserRepository and use User. In the service, you bind UserRepository to EloquentUserRepository. Finally, in the controller you’re storing an instance of User?? There it’s quite confused (because of too much magic maybe), I suggest renaming “User” as “UserModel” or “UserRepository” to notice quickly what we’re referencing somewhere, in the middle of hundreds controllers for example.
    Same in UserRepository, it’s an interface and we know it’s not instanciable. BUT, thanks to StorageServiceProvider, you call “UserRepository”, it calls “EloquentUserRepository”. To be clearer, is there a way to rename the interface “UserRepositoryInterface” and still having “UserRepository” calling “EloquentUserRepository” ? Thank you for your articles !

    • Ah yeah, I see what you mean. Yeah you can name any of these classes whatever you want really, the more descriptive the better I would say, especially if your code is going to be worked on by multiple people.

      Thank you, I’m glad you are finding them useful :)

      • Max13

        I did :D But I can’t bind “UserRepository” to “EloquentUserRepository” (I’ve named my interface *Interface), does “->bind()” requires the classes to exists or to be declared ?

        • Hmm, I’m not sure what you mean? How does that class not exist?

          • Max13

            Sorry, I explain again. For clarity I’ve renamed my “UserRepository” interface (and .php file) to “UserRepositoryInterface”. I see “$this->app->bind()” as a conveniant way to say “When I want UserRepository, give me EloquentUserRepository”. So, as I renamed my UserRepository, it makes no sense to call “UserRepositoryInterface” in my code to receive an EloquentUserRepository, does it ?

            So now, as expected, when I ask “UserRepository”, it doesn’t exist, so it makes the use of “bind()” a bit more confusing.

            Is there a way (if it’s intended to) to call an instance of UserRepository which would be magically an EloquentUserRepository (which implements UserRepositoryInterface), using “bind()” as you did ?

          • Ahhhh I see what you mean. So you kind of what to give it an alias? You could probably work some magic with the IoC container to make this work, but to be honest, I quite like the example in the docs under the “Binding An Interface To An Implementation” header http://laravel.com/docs/ioc#practical-usage

            Is that what you mean?

          • Max13

            Kind of an alias, yes! But “Binding an Interface to an Implementation” isn’t what you’re doing on your examples? Anyway, making an alias isn’t that hard, I think i’ll follow laravel’s doc or yours and continue.

            Thank you !

          • Hmm, no UserRepository is just an interface, see https://github.com/cribbb/cribbb/blob/master/app/Cribbb/Storage/Post/PostRepository.php

            No problem :) If you want to ask any questions, just give me a shout!

  • Pieter Botha

    These tutorials are amazing. Thanks so much! Good to see someone
    talking about abstracting away the data-layer. Repositories are
    fantastic, and not nearly used enough. Not gonna comment on “easily” switching out databases but for testing alone repositories have huge advantages. Thanks again.

    • Thanks :)

      Haha yeah, that was a bad example, but I think most people could see the benefit despite my bad analogy :p

  • Kieran

    A great post, makes sense now. I was over complicating in my mind. One
    question, in the Service provider can I simply add more bindings, like
    so:

    app->bind(
    ‘CribbbStorageUserUserRepository’,
    ‘CribbbStorageUserEloquentUserRepository’
    );

    $this->app->bind(
    ‘CribbbStorageUserProductsRepository’,
    ‘CribbbStorageUserEloquentProductsRepository’
    );

    $this->app->bind(
    ‘CribbbStorageUserStockRepository’,
    ‘CribbbStorageUserEloquentStockRepository’
    );
    }

    }

    Would this be correct?

    Thanks

    • Absolutely! That’s exactly what I do too.

      I tend to have a Service Provider for all of my “storage” bindings. With Laravel you can do pretty much what you want, but I think using grouping them together in one Service Provider makes a lot of send.

      Glad you found it useful :)

      • Chrystopher Salvador Medina Re

        thanks @Phillip Brown.

        you are an excellent teacher, keep it up (y)

      • Johan Nyberg

        Just to be a pain in the ###, but why create the subdirectory User? Wouldn’t it make more sense to have all the repos living under Storage?

        • You could, but then you would end up with lots of files under that directory. I think it is better to organise each interface and implementation(s) under their own directories.

  • Jorge Luis Veliz

    hi, your post is awesome, i made it but i have a question

    why in the terminal i have to writte composer dump-autoload when i put a new namespace it is ugly

    sorry my english!!

    • It’s because Composer keeps a cache of the filenames. When you change something you have to tell Composer to dump it’s cache.

      It’s just so Composer can load your files quicker.

  • wisewarrior

    Nice article! I am trying to understand the naming convention of the ‘storage’ directory. I see this folder in many of the explanations of Laravel / Repository Pattern. Would you mind explaining why you chose this name? Thank you

    • Hmm, it’s just a random word really. I guess because you wouldn’t want to say “database” because it wouldn’t necessarily be a database, just a persistent storage system. So storage is a neutral word for saving something.

      I actually don’t use the storage namespace anymore, I usually just keep my repositories under a repositories directory.

      Hope that helps! :)

      • wisewarrior

        :-)!

  • Robert B

    Do you happen to have a tutorial on abstracting the authorization away from the controller? Two examples:

    1) I have a Projects controller and you need to be logged in to view any project pages. I’m using Sentry and have a ‘beforeFilter’ in the construct.

    2) In the same Project controller, I retrieve projects for a user using $projects = $this->user->find(Sentry::getUser()->id)->projects()->get();

    Obviously having relationships in my User and Project models. Would be nice to switch out authentication in the future if I decide to do so.

    • Hi Robert, no I haven’t covered authorisation yet, but I definitely will (hopefully soon). Subscribe to my email list so you don’t miss it :)

  • Liked it a lot! How did you manage validation with that structure? Thank you! :)

  • Fin

    Thanks for the article Phil. I was looking for laravel best practice and this article feels like revelation to me. But i got a situation here, i followed every step of your instructions, but laravel throw me the following error :
    “Class CribbbStorageUserEUserRepository does not exist”
    It’s very odds because i have double-checked the filenames and path.
    Would you tell me what’s wrong with my code. here’s my code:
    http://stackoverflow.com/questions/23056080/laravel-reflectionexception-error-repository-doesnt-exist

    • Did the answer on StackOverflow sort it for you?

      • Fin

        Yes it works for me. thanks :)

  • Fin

    Hey Phil. I have implemented your technique in my user registration with succeed. But, I failed in user authentication. I tried to use Auth::attempt() in EloquentUserRepository becuse I presumed the “use User” at the top of the class is some kind of reference to User model which is implemented Auth. But Laravel throw me this error :

    Class ‘CribbbStorageUserAuth’ not found

    would you tell me what is wrong? is there some kind of different technique to do user authentication with this repository pattern?

    Thanks.

    PS: sorry for my English. it’s not my native language :)

    • Yeah I wouldn’t do authentication in your repository. Your repository is only for storing data, it’s not also for authentication.

      If you keep reading this series I will be covering authentication in more depth :)

      You are getting the error because the Auth class also needs to be among the use statements at the top of the class. But like I said, you don’t want to be doing authentication in your repository.

      • Fin

        I add the Auth class and it works. But you’re right , it’s seems not relevant to store data there.that’s why we call it repository.
        But I still like the idea to separate my authentication from the controllers, just like this repository concept, it keeps my controller tidy. Do you have any idea how to do that?
        I am waiting for your next tutorial on that topic. Thanks.

      • LightVision Coder

        Well, actually it make sense to make authentication with UserRepository since Auth:: will return eloquent and this is not what you want, you want an implementation of UserRepository

  • Hmm, interesting topic. I haven’t followed this subject though but maybe checking out the previous tppics may help.
    By the way thanks for sharing Philip.

  • Johan Nyberg

    Hi again Phil, and thx for amazing tuts!

    I’ve followed along, but in the end when I run /user I get nothing.. A blank page (also checking source, empty). I have three users in the Users table.

    Do you have a tip on how I could debug this?

    I’ve put my code here, if you want to have a look:

    https://github.com/johannyberg/cribbb

    • Thank you Johan :)

      Are you getting an error in the log? Your UsersController.php should be without the “s”. That might be the issue.

      • Johan Nyberg

        Thanks for noticing that typo. But, alas, no cigar. Still a blank page. And the weird thing – nothing in the laravel.log.. weird..

        • Johan Nyberg

          This is embarassing. At last I found the errors. It was two semicolons missing from the namespace in UserRepository and EloquentUserRepository.. *blush*

  • Ross Edman

    Hey Philip,

    Thanks for the article. It is really good work. All of yours are in fact. I have read quite a bit on the Repository Pattern with Laravel but one thing I have a hard time with is what should be in the models and what should not? What should be in the Repository patterns and what should not?

    For instance, I understand any CRUD functions seems to make sense going in the Repository to abstract away from the Controllers, and relationships make sense staying in the Model because of the ORM.

    What about everything in between? Any advice? Are presenters an options? Or even Attributes?

    • Hi Ross, thank you :)

      Yeah, that is a difficult thing to understand, I still don’t think I’ve found the definitive answer. I usually draw the subjective line between what is right, verses what feels wrong.

      I’ve actually wrote about using Presenters http://culttt.com/2014/03/03/model-presenters-laravel-4/ so I usually make that a different layer.

      For attributes, I usually use Eloquent’s mutators, so that would be in the model.

      I think it’s hard to know what is “right” and what is “wrong”. I’d say if it feels right in your project, then that is good enough.

      • Ross Edman

        Thanks for the response. I wanted to make sure there wasn’t a standardized way to do this to keep your codebase organized. I love the Presenter idea and have started using these as well.

        I guess for now, keeping anything to do with Eloquent in the models makes sense because it is directly related to Eloquent. Anything that can be substituted or abstracted can be put into my library.

        Thanks for all your insights. Sometimes I feel half crazy wondering about these things.

        • Yeah, my understanding and confidence in just about any topic regarding programming fluctuates on a daily basis. I think a lot of people feel like that!

  • David John

    I think if you choose integrated and well-designed Content Management System, such as Doptor CMS, it will answer all your questions and will provide you with the tools to build and maintain a
    sustainable web presence. I did.

    • Thanks David (I think spam comments normally have a link) ;)

  • Alfred Nutile

    Great work putting these complex concepts into a very practical example.

  • heihachi88

    Thanks for article. But how to save data in controller when you are using repositories?

    public function saveCreate() {
    $new = Input::all();

    $this->page->title = Input::get(‘title’);
    $this->page->body = Input::get(‘body’);
    $this->page->slug = Slug::make($this->page->title);
    $this->page->save();

    return Redirect::action(‘PageController@home’);
    }

    this is not working anymore, because save() isn’t a static method.

    • The saving happens inside the repository, not the controller.

  • Where should I left the repositories files? app/repositories? What it’s your recommendation?

    • I usually put all of my application’s code under a namespace. So repositories would be CribbbRepositories

  • Johan Nyberg

    This is a real newb question, but how does the UserController actually get an instance of the $user sent into the constructor? I can see that the “use” keyword is used to define the class User being the UserRepository, but how does it get instantiated?

    • Laravel’s IoC container will automatically resolve it for your based upon the type hint. It’s part of the Laravel magic.

      In normal PHP you would have to actually create the controller, inject the dependencies and then call the method.

      • Johan Nyberg

        Wow.. I guess I just have to get used to the awesomeness of that then. :)

        • Yeah Inversion of Control is a pretty awesome part of Laravel 4 :)

      • But what happens if there are multiple implementations of an interface? e.g. a StorageInterface with a DatabaseStorage and FileStorage class?

        • Then you would just specifiy which implementation you wanted.

  • Johan Nyberg

    Just so you know, you’re using the route /user and UserController in singular here, and everywhere else in this (btw, awesome) blog series in plural.

    What’s the best practice? Model names in singular and controller names in plural?

    • Ah yeah, I really do need to pick a standard way.

      There isn’t really a best practice as long as it’s consistent. I’ll probably use plural though because I prefer plural routes.

  • 尤川豪

    Hi!
    I have a question:
    So you create the service provider file
    In app/lib/cribbb/storage.

    But I think service is the core of whole application. Isn’t it weird to put this kind of files in ‘lib’ folder? Lib should only contain some tools code, isn’t it?

    I know it may not be a problem, but I just think it’s kind of ugly structure.

    • No I disagree, I think the repositories are core to your application and are no concern of the framework. Your namespaced code is part of your application’s domain.

      With that being said, if you don’t think the structure is right for you, you are free to use a different structure. Laravel is very flexible in that sense.

      • 尤川豪

        I see. I will think about this.
        Your solution is much more elegant than a lot of php projects I have seen.
        Thanks anyway!

        :)

  • Yeah I think using a base repository is a great way to abstract repeated logic.

  • Pingback: How to structure testable Controllers in Laravel 4 | Culttt()

  • Pingback: Building out RESTful Controller methods in Laravel 4 | Culttt()

  • Pingback: Creating Entities in Laravel 4 | Culttt()

  • Pingback: Laravel 4 Cache as a Service | Culttt()

  • Pingback: Working with Pagination in Laravel 4 | Culttt()

  • Amit Aggarwal

    Awesome Dude .. Thanks a lot .

    I have a question :
    When calling any function ( repository function ) in our controller , we are using $this->user->all(); … Isn’t it possible to call like User :: all() in static way ?

    If yes , can you please explain me how ?

    Thanks
    Amit Aggarwal

    • Hmm not really. I guess you could probably write a Laravel facade to do it, but I wouldn’t bother. It’s not worth the syntactical sugar.

  • Vincent Cohen

    Perhaps a stupid question, but I don’t understand something and perhaps I’ve over misread.. but how does the repository know what model to use to create a new user? I have for example the UserRepository and a User model (created when following http://culttt.com/2013/09/09/registration-authentication-laravel-4/) and when using the UserRepository create method a new user is created. But I don’t see how the repository knows that it needs to use the User model (which handles the saving of data).

    I see everything working in my database but have no clue why

    • You inject and instance of the User model through the __construct() method and then use this instance of Eloquent to interact with the database :)

      • Vincent Cohen

        Totally missed that, I see now! Thanks!

  • Romaldy Minaya

    Hi Philip Brown, I got a simple question.

    What would be the best solution if you want to get all the users but in one controller you want them ordered by name and in another ordered by creation date, in another controller you would want the users to be paginated and in another just the first 5 records.

    Should i declare one method for each approach in my iUserRepository ?

    Thanks anyway :)

    • You could just define a private method that returns an instance of the query builder, and then use it to add the constraint for each public method.

  • Ariel Calcaño

    Excelent Post.

    There is a problems for organizing StorageServiceProvider in a SUB/SUB/SUB/StorageServiceProvider.php ?

    I have a “Class not found” error when I try it, but when I put the provider in SUB/SUB/StorageServiceProvider.php everything work fine.

    Thanks for you contribution Philip, God bless you!

    • Sounds like you need to correct your namespaces.

      Thank you Ariel :)

  • Darron Driver

    Thanks for the great article. Interfaces make sense now. One thing though – if I try use eager loading:

    $this->user->with(…) I get a Call to undefined method…

    Would I have to build out the interface with all the relevant Eloquent methods (every time) to get it working, or is there way to inherit these methods into the interface?

    • $this->user is the repository, not the model, so if you wanted to add a with() method, then yeah you would need to define it on the interface.

      A better way (IMHO) for eager loading is to pass the eager loader requirements as an argument. For example you would have a find(array $with = []); method that would optionally accept an array of relations to eager load.

      Have a look at this post http://culttt.com/2014/03/17/eloquent-tricks-better-repositories/

  • David

    In the first laravel 4 tutorial you use the name “UsersController” however in this, you use the name “UserController”. Is the naming convention to use plurals for controllers or singular?

    • It’s up to you really, there is no convention on what it should be.

  • scruffmcbuff

    I’m getting the error: Class ‘codestorestorageStorageServiceProvider’ not found

    • Either your namespaces, filenames or class names are inconsistent and so Composer can’t load them.

      Your namespaces should begin with a capital letter too.

  • Pingback: What are the benefits of using Repositories? | Culttt()

  • Dylan Pierce

    You. You are awesome

  • I am filtering the result with ajax datatables with chumber/datatable package.
    Can you point me where is the best place for filtering code?

    My controller currently looks like this:

    public function getDatatable() {
    return Datatable::collection(
    PricelistView::select(
    [
    "destination",
    DB::raw("round(rateinitial, 3) AS rateinitial"),
    DB::raw("round(5/rateinitial) AS minutes")
    ])
    ->where("idtariffplan", "=", 22)
    ->groupBy("destination")
    ->get()
    )
    ->showColumns('destination', "rateinitial", "minutes")
    ->searchColumns('destination')
    ->orderColumns('id', 'destination')
    ->make();
    }

    • I’m not familiar with that package, so I don’t really know. I’m not really sure what you mean by “filtering”, but I probably wouldn’t have any of the code in the controller.

      • I understand this code is not the best place in the Controller, so need to move somewhere else. I need an advice who are expert in Laravel, where is the best place for a code like this in the MVC structure in Laravel.

        Because the Model is the right place to manipulate with DB data I prefer to put somewhere in the Model.
        Filtering means jQuery datatables is sortable, paginateable and searchable / filterable. So I send the filter conditions with ajax, process it somewhere and send back the results to the view.

        This is the reason why I put this code into the controller (because I communicate between the view and the model)

        I try to rewrite my code following your howto, so I need advice.

        • Hmm, well it’s hard to say without know the big picture of your application, so I’ll try to give you some general advice that should hopefully guide your decisions.

          The Controller should be disposable, so you don’t want to put the logic in there.

          I’m guessing that the Model is also probably not the place to put this kind of logic either. Eloquent models are already doing a lot of work, they don’t need to also be concerned with filtering or displaying data.

          I would say you’re best off putting that code into a service class that can be injected into the Controller. You would then keep all of the logic that you need internally to that class, but you provide a generic interface that can be utilised from the Controller.

          Does that make sense?

          • I think I lost in DDD :)
            This is the 3rd day just reading and reading the tutorials, but yes, it helps a lot.
            Thank you
            Peter

          • No problem Peter, we’re all learning together :)

  • AB

    Thanks for this nice tutorial. I am new to Laravel. I have a query. If I need to switch from Eloquent to some other ORM, I need to define a separate model class User based on that ORM, right? The good thing here is I don’t have to touch the controller code. Any other advantages of Dependency Injection. I have learned that it makes testing easier. Can you do a post on testing in Laravel or do you already have one? Much appreciated.

  • dianikol

    Hi and thank you for a great article!

    I was building a simple app where i need to filter some results based on some criteria. Usually when you start build a app you don’t know if in the future will need to change your database storage.

    So i used a repo using eloquent of course. For filtering result sounds a good idea to use scopes since it makes really readable code.

    I read somewhere that chaining in repos is a bad idea because it is still bind the interface with eloquent and it is true. But that way if i avoid to chain in the repo i lose a great feature such as scopes in order to use repository pattern.

    So at least i see it for now using repos for database layer is good only for testing purposes.

    A better use case of the repository pattern is when you want to implement mailing or billing services where swapping them with others is going to be really easy.

  • Yashaswini

    Hi , this is a great article which throws light on how to implement repository pattern. My doubt is regarding auth process. WIth this in use, when we use Auth::attempt() , it throws an error of Call to undefined method ServicesUserUserFacade::newQuery(). Is it because now our model is more of repository which we are talking to rather than eloquent itself? Should we change it in auth.php ? Could you please throw some light on this ?

    • Hmm, I’m not sure why you’re getting that error, but I don’t think it is to do with using Repositories. Behind the Repository you are still using the Eloquent model.

  • jmvc

    Hi Philip! cool blog! I have a question. What’s the difference of switching the database driver in the app/config/database.php file with creating another MongoRepository? Is it cause by doing the latter, you change the ORM methods(Eloquent) to a native MongoDb class(without eloquent)? hoping for your reply. Thanks!

    • Thank you :)

      Switching the database config would mean you would still be using Laravel’s Eloquent. Creating a Repository means you would be switching the ORM.

      • jmvc

        Thanks for bringing light!

  • Juan

    Hello Philip,

    I have a question about the repository pattern. I have 2 repositories (Patient and MedicalHistory) and I need know if a patient have and active medical history. I don’t want do this in the controller because I think I will need this in many parts of my app. So I was thinking add it in the Patient repository as a method hasMedicalHistory(), but i want to know if is ok use dependency injection for MedicalHistory in the Patient repository?

    I share part of code for clarity.

    http://goo.gl/s1oczx

    Thank you very much for taking the time to read. Greetings!

    • Yeah I think that would be fine. It’s inevitable that you will find yourself in that situation. Usually one model will be responsible for another model so it makes sense to allow retrieval from a different repository.

      It’s not perfect, but I don’t see it as a problem. If it does start to cause a problem I would perhaps take a closer look at the business requirements of the application to see if you are missing a key bit of information.

  • Oli

    Once again Philip, a really well written tutorial. I really appreciate how good you are at taking complex theorems and breaking them down into the 4P’s (problem, promise, proof, proposition). Top marks.

    What I enjoy about your work is how looking over the tutorial archive, I can see how you’ve grown as a developer. It allows myself to do the same! Infact I have tried coupling this tutorial with your “Advanced Validation as a Service for Larvel 4” (http://culttt.com/2014/01/13/a…. I make sure that I keep my nice set of user validation rules in my applib folder and then initiate the validation through my user model which is referenced in my EloquentUserRepository. The issue I have is when the validation produces error messages through the $errors function I get:

    “Undefined property: applibStorageUserEloquentUserRepository::$error

    Just wondering how joining your two tutorials up, how I could fix this?

    • Thank you Oli :)

      That error just means you don’t have an $error property on the repository.

  • Dome

    Thanks for your post! I am new in Laravel and it was very helpful for me. Just i dont know why i cant use raw query in EloquentUserRespository. If i try i got back the errore: class UserDB not found. can somebody help me?

    • You need to add the correct namespace for the DB facade. Add use IlluminateSupportFacadesDB; to the top of your class.

  • Rdharma

    Just a quick question. How would you handle any repository exception? Such as when creating a record, there is a integrity violation and it throws a QueryException, is there a way to provide a more user-friendly message (maybe the e-mail address already exists) by catching the exception and setting the error message bag…

    • Yeah I would try and deal with those types of errors through validation. If an exception is thrown it’s probably a sign that something has gone wrong, rather than a validation error.

  • Novica Vukobratovic

    Got a question. When I use repository for any Model really, should I also make methods on it like “listAllUsers()” in it, which would do something like return User::lists(“name”,”id”); or should I just make a general “all()” method in the repo and then call $users = $this->userRepo->all()->lists(“name”,”id”); in the controller ? Since the collection would be returned from the User::all() call and method “lists()” would then be called on the collection ( not using eloquent ), which seems ok to do, but what happens if I use mongo later as DB layer ? How would you return the same type of collection by using “all()” method on the repository by using Mongo, instead of using Eloquent, so that the call which is in controller “$users = $this->userRepo->all()->lists(“name”,”id”);” would still work ?

    • Hmm, well if you want to really isolate your persistence layer you would probably be best off using defined methods in an interface. So yeah, you would need to create the listAllUsers() method.

      • Novica Vukobratovic

        Great, that’s all I wanted to know :) Since I guess there’s no point in isolating only DB interaction Eloquent specific things, but all Eloquent specific things as well.

  • Carl Mabugay

    Is there any way that i can adapt this technique on L5? how? Thanks for this great article.

    • Yeah for sure, everything in this tutorial will work in Laravel 5 :)

  • Thank you for this great post! Laravel conventions hurt my head!

  • Bitfal

    Why do you use binding? Why don’t you create just an abstract Eloquent class with all code implemented, and then just create an empty User class which extends the abstract Eloquent class? Then you only have to change the the “x extends y” part. (class UserRep extends EloquentRep -> class UserRep extends MondRep)

  • Adnan Siddiqi

    So in the file `UserRepository` it will itself figure out how to get Eloquent methods?

    • UserRespository is just the interface, the EloquentUserRepository implementation deals with Eloquent.

      • Adnan Siddiqi

        Pardon, I meant, do I need to add path to Eloquent so that “`EloquentUserRespository“` can call Eloquent methods?

        • Yes, the EloquentUserRepository is either injected with an instance of the Model, or just calls the methods directly on the Model :)

  • amohammadi

    awesome article.so tnx philip