简体   繁体   中英

Laravel Repositories and Eloquent Models

After reading a few tutorials and mostly watching videos on Laracasts , I was considering adding an abstraction layer in my website using Repositories which would be injected in my Controllers through an interface. The Repositories are there to abstract how the Model is retrieved and hide some business logic. Using the Bind method available in Laravel , this seemed super easy and convenient.

This sounds super interesting to add unit tests to a project, but I fail to understand how the Model should be handled.

For example, let's say we're trying to hide the good old User model behind a repository, by creating:

interface UserRepositoryInterface {
    public function getAll();
    // ...
}

Then, to support the standard User model provided by Laravel, defined as:

class User extends Eloquent implements UserInterface, RemindableInterface {
    // ...
}

We create an Eloquent implementation of the UserRepositoryInterface :

class EloquentUserRepository extends UserRepositoryInterface {
    public function getAll() {
        return User::all();
    }
}

The part that I don't understand is that now, the Repository doesn't return a "generic" Model , it returns an Eloquent model! It doesn't make sense to me that other Repositories should return the same type of Model , and if it's not the case, what's the point of having Repositories if there is no correlation at all between the Models returned?

What then is the proper usage of the Repository pattern within Laravel ?

Repositories in Laravel help keep controllers thin and dumb.

Controllers get to handle any route or data parsing before handing to the repository, and returning data in proper formats.

Repositories get to handle the models.

If you have both of these functions are in the same controller method, you have trouble determining if the issue is in the parsing of the data from the input, or the requesting of data from the model.

This separation allows use to make sure the controller is handing appropriate data to the repository . That the repository is performing the appropriate validations and accessing the model in the correct manner, and that all of these are returning data of the correct type.

The repositories returned model can be tested for type using instanceof :

public function testAllReturnsCollection()
{
    $collection = $this->machineRepository->all();
    $this->assertTrue($collection instanceof \Illuminate\Database\Eloquent\Collection);
}

public function testFindReturnsMachine()
{
    $model = $this->machineRepository->find($this->machineId);
    $this->assertTrue($model instanceof Machine);
}

This type of testing can also be done with Mocking , but when working with models I prefer to use a test database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM