Search code examples
laravelrepository-patternlaravel-5solid-principles

How to keep helper methods when using Repository pattern in Laravel 5?


When working with repository pattern we have interface and some repository classes which implement this interface. If I'm not mistaken, one of the SOLID principles says that those repository classes should return the same type of data for each interface method so that if we switch implementation of the interface nothing breaks down.

If I have an eloquent repository class, which returns an array of eloquent classes of all users, like return User::all(), I have not a simple array but an array of Eloquent models. So instead I might want to use toArray() to return simple array, so that if I switch my implementation of the interface to some other ORM (for example UserDoctrineRepository or I don't know...) everything will still work.

If I understand correctly, inside UserEloquentRepository we use an eloquent model class to help us get data using Eloquent. However, inside my model (User class) I might have some helper methods, like getFullName(). If I simple use toArray() inside UserEloquentRepository I won't get this helper method in my controller, and, eventually in my view.

In other articles I've read they keep it like return User::all(), however, it means that I'm still coupled to Eloquent as I don't get a simple array, but an eloquent objects array


Solution

  • What you get from User::all() or basically every Eloquent query is a Illuminate\Database\Eloquent\Collection. The problem is that when you call toArray() on the collection it will convert all the items of the collection into an array too and you loose all the methods of your model. Instead you can call all() on the collection to get to the array of model objects:

    $collection = User::all();
    return $collection->all();
    

    Yes that still means you will have Eloquent specific models in your resultset however if you don't use Eloquent features like attribute accessors you will have an easy time replacing it with another type of model.