laraditz/repository
Model wrapper repository implementation for Laravel. Provides a simple repository pattern layer around Eloquent models to centralize data access and keep controllers/services cleaner and more testable.
Installation:
composer require laraditz/repository
Publish the config (optional):
php artisan vendor:publish --provider="Laraditz\Repository\RepositoryServiceProvider"
Define a Repository:
Create a repository class extending Laraditz\Repository\Repository:
namespace App\Repositories;
use App\Models\User;
use Laraditz\Repository\Repository;
class UserRepository extends Repository
{
public function model()
{
return User::class;
}
}
Register in Service Provider:
Bind the repository in AppServiceProvider:
public function register()
{
$this->app->bind(UserRepository::class, function ($app) {
return new UserRepository();
});
}
First Use Case: Inject the repository into a controller/service and use it like Eloquent:
public function index(UserRepository $userRepo)
{
$users = $userRepo->all(); // Equivalent to User::all()
return response()->json($users);
}
Basic CRUD Operations:
// Create
$user = $userRepo->create(['name' => 'John']);
// Read
$user = $userRepo->find(1);
$users = $userRepo->all();
// Update
$userRepo->update(1, ['name' => 'Jane']);
// Delete
$userRepo->delete(1);
Query Scoping:
Override scope* methods in your repository:
public function scopeActive($query)
{
return $query->where('active', true);
}
Usage:
$activeUsers = $userRepo->active()->get();
Dependency Injection:
Bind repositories in AppServiceProvider for type-hinted usage:
$this->app->bind(
\App\Repositories\PostRepository::class,
function ($app) {
return new PostRepository(new Post());
}
);
Repository Facades (Optional): Create a facade for global access:
// app/Repositories/Facades/Repository.php
namespace App\Repositories\Facades;
use Illuminate\Support\Facades\Facade;
class Repository extends Facade
{
protected static function getFacadeAccessor()
{
return 'user.repository'; // Must match config binding
}
}
Bind in AppServiceProvider:
$this->app->bind('user.repository', function ($app) {
return new UserRepository();
});
Unit Testing: Mock repositories in tests:
$mockRepo = Mockery::mock(UserRepository::class);
$mockRepo->shouldReceive('find')->andReturn($userMock);
No Built-in Caching: The package doesn’t include caching. Add manually:
$user = $userRepo->remember(1, 60); // Cache for 60 seconds
Missing Soft Deletes:
If your model uses SoftDeletes, ensure the repository handles it:
public function delete($id)
{
$model = $this->find($id);
$model->delete(); // Soft delete
}
No Default Scopes: Unlike Eloquent, repositories don’t auto-apply global scopes. Define them explicitly:
public function __construct()
{
$this->applyScopes(['active']);
}
Transaction Handling: Repositories don’t auto-commit transactions. Wrap operations manually:
DB::transaction(function () use ($userRepo) {
$userRepo->create([...]);
$userRepo->update([...]);
});
Enable Query Logging:
Add to AppServiceProvider:
DB::enableQueryLog();
$queries = DB::getQueryLog(); // Inspect in debuggers
Check Model Binding:
Ensure model() returns the correct class name (e.g., App\Models\User).
Override Default Methods:
If find() or all() don’t work, override them:
public function find($id)
{
return $this->model->findOrFail($id);
}
Custom Query Builders: Extend the repository to add methods like:
public function search($query)
{
return $this->model->where('name', 'like', "%{$query}%")->get();
}
Event Dispatching: Trigger events post-operation:
public function create(array $data)
{
$model = $this->model->create($data);
event(new UserCreated($model));
return $model;
}
API Resource Integration: Pair with Laravel’s API Resources for responses:
public function toResource($model)
{
return new UserResource($model);
}
Repository Interfaces: Define interfaces for better testability:
interface UserRepositoryInterface {
public function find($id);
public function all();
}
How can I help you explore Laravel packages today?