Laravel Base Repository
, (*1)
An abstract repository class for your Eloquent repositories that requires minimal config to get started., (*2)
Features
- 2 minute setup.
- 10 useful methods out of the box such as
getById.
- Flexible relationship support including eager loading..
- Optional easy to use Caching.
- Optional 404 exceptions when items aren't found.
Quick Start
Install via Composer., (*3)
composer require dannyweeks/laravel-base-repository, (*4)
Extend your repositories with Weeks\Laravel\Repositories\BaseEloquentRepository., (*5)
Add the $model property to your repository so the base repository knows what model to use., (*6)
namespace App\Repositories;
class PostRepository extends \Weeks\Laravel\Repositories\BaseEloquentRepository
{
protected $model = \App\Models\Post::class;
}
That's it! Let's test it out., (*7)
$repo = new App\Repositories\PostRepository();
var_dump($repo->getById(1)); // Returns the Post with an ID of 1.
var_dump($repo->getAll()); // Returns a collection of all your posts.
Usage
Your repositories must extend the BaseEloquentRepository class and have the properties:
- protected $model: the name of your model (including it's namespace)
- protected $relationships: (Optional) an array of the methods available to be included when retrieving items., (*8)
$posts = new App\Repositories\PostRepository();
$firstPost = $posts->getById(1);
$allPosts = $posts->getAll();
$allPostsIncludingComments = $posts->with('comments')->getAll();
Be sure to check out the example., (*9)
Available Methods
See the repository interface class for the full API., (*10)
Relationships
Relationships are defined in the repository but are not eagerly loaded automatically., (*11)
Relationships can be loaded in the following three ways using the with() method:, (*12)
-
$postRepository->with('all')->getAll(); retrieve all relationships defined in the repository class
-
$postRepository->with(['comments', 'author'])->getAll(); retrieve relationships using an array
-
$postRepository->with('comments')->getAll(); retrieve relationship using a string
An Example
This example shows how your model, repository and controller could be set up., (*13)
app\Models\Post.php, (*14)
namespace App\Models;
class Post extends Illuminate\Database\Eloquent\Model
{
public function comments()
{
return $this->hasMany('App\Models\Comment');
}
public function author()
{
return $this->hasOne('App\Models\User');
}
}
app\Repositories\PostRepository.php, (*15)
namespace App\Repositories;
use Weeks\Laravel\Repositories\BaseEloquentRepository;
class PostRepository extends BaseEloquentRepository
{
protected $model = App\Models\Post::class;
protected $relationships = ['comments', 'author'];
}
app\Http\Controllers\PostController.php, (*16)
namespace App\Http\Controllers;
use App\Repositories\PostRepository;
class PostController extends Controller
{
protected $posts;
public function __construct(PostRepository $posts)
{
$this->posts = $posts;
}
public function show($id)
{
// get the post and eagerly load the comments for it too.
$post = $this->posts->with('comments')->getById($id);
return view('posts.show', compact('post'));
}
}
HTTP Exceptions
To enable http exceptions (like Eloquent's findOrFail method) on a repository just have it use \Weeks\Laravel\Repositories\Traits\ThrowsHttpExceptions;., (*17)
If the below methods return null they will throw a 404 error instead of returning null., (*18)
getById
getItemByColumn
An example using the ThrowsHttpExceptions trait., (*19)
namespace App\Repositories;
use Weeks\Laravel\Repositories\BaseEloquentRepository;
use Weeks\Laravel\Repositories\Traits\ThrowsHttpExceptions;
class PostRepository extends BaseEloquentRepository
{
use ThrowsHttpExceptions;
protected $model = App\Models\Post::class;
}
You can temporarily disable HTTP exceptions by chaining disableHttpExceptions() before performing a query. For example:, (*20)
$posts = new PostRepository();
$post = $posts->disableHttpExceptions()->getById(1000); // returns null rather than throwing a 404 error.
Caching
To enable caching on a repository just have it use \Weeks\Laravel\Repositories\Traits\CacheResults;., (*21)
By doing this all the repository 'read' methods cache their results using Laravel's caching system., (*22)
// Methods that cache when using the CacheResults trait.
getAll
getPaginated
getForSelect
getById
getItemByColumn
getCollectionByColumn
getActively
An example using the CacheResults trait., (*23)
namespace App\Repositories;
use Weeks\Laravel\Repositories\BaseEloquentRepository;
use Weeks\Laravel\Repositories\Traits\CacheResults;
class PostRepository extends BaseEloquentRepository
{
use CacheResults;
protected $model = App\Models\Post::class;
protected $relationships = ['comments', 'author'];
protected $nonCacheableMethods = ['getById'];
protected $cacheTtl = 30;
}
You can force the result of a request not to be cached by adding the method name to the $nonCacheableMethods property of your repository. See example above., (*24)
By default the ttl of a cache item is 60 minutes. This can be overwritten by updating the $cacheTtl property of your repository. See example above., (*25)
Caching can be disabled programatically by calling disabledCaching() on your repository. This method returns the repository to enable method chaining e.g. $repo->disableCaching()->getAll();., (*26)