Installation
composer require thenandan/therepository
Add the service provider to config/app.php under providers:
Thenandan\Therepository\TherepositoryServiceProvider::class,
First Use Case: Basic Repository
Define a model (e.g., User) and its corresponding repository:
php artisan make:repository User
This generates:
app/Repositories/UserRepository.php (interface)app/Repositories/Eloquent/UserRepositoryEloquent.php (implementation)Register the Repository
Bind the repository in a service provider (e.g., AppServiceProvider):
$this->app->bind(
\App\Repositories\UserRepository::class,
\App\Repositories\Eloquent\UserRepositoryEloquent::class
);
Usage in Controller
use App\Repositories\UserRepository;
class UserController extends Controller {
protected $userRepository;
public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}
public function index() {
$users = $this->userRepository->all();
return view('users.index', compact('users'));
}
}
CRUD Operations
// Create
$user = $this->userRepository->create(['name' => 'John', 'email' => 'john@example.com']);
// Read
$user = $this->userRepository->find(1);
$users = $this->userRepository->all();
// Update
$user = $this->userRepository->update(1, ['name' => 'Updated Name']);
// Delete
$this->userRepository->delete(1);
Query Scoping
Use scope* methods for reusable queries:
// In UserRepositoryEloquent.php
public function scopeActive($query) {
return $query->where('active', 1);
}
// Usage
$activeUsers = $this->userRepository->scopeActive()->get();
Transactions Wrap operations in a transaction:
$this->userRepository->transaction(function ($repository) {
$user = $repository->create(['name' => 'Alice']);
$repository->create(['name' => 'Bob']);
});
Events and Observers Trigger events via the repository:
$this->userRepository->fireModelEvent('creating', $user);
Dependency Injection Prefer constructor injection for repositories in controllers/services:
public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}
Testing Mock repositories in tests:
$mock = Mockery::mock(UserRepository::class);
$mock->shouldReceive('find')->andReturn($user);
$this->app->instance(UserRepository::class, $mock);
Custom Logic Extend the base repository for domain-specific methods:
// app/Repositories/UserRepository.php
public function getAdmins() {
return $this->model->where('role', 'admin')->get();
}
API Resources Pair repositories with API resources for consistent responses:
return UserResource::collection($this->userRepository->all());
Naming Conflicts
Avoid naming custom methods all(), find(), or other reserved words to prevent overriding base functionality.
Model Binding Ensure the repository’s model property is correctly set in the implementation:
protected $model = \App\Models\User::class;
Mass Assignment
Be cautious with create()/update()—validate input or use $fillable in the model to avoid mass assignment risks.
Lazy Loading
Avoid eager loading in repositories unless necessary (e.g., with() in queries) to prevent N+1 issues.
Query Logging Enable Laravel’s query logging to inspect generated SQL:
\DB::enableQueryLog();
$users = $this->userRepository->all();
dd(\DB::getQueryLog());
Repository Events
Debug events by listening in EventServiceProvider:
protected $listen = [
'eloquent.saved: App\Models\User' => [
\App\Listeners\LogUserActivity::class,
],
];
Transaction Rollbacks
If a transaction fails silently, wrap in a try-catch:
try {
$this->userRepository->transaction(...);
} catch (\Exception $e) {
\Log::error('Transaction failed: ' . $e->getMessage());
}
Custom Drivers Extend the base repository to support non-Eloquent drivers (e.g., API clients):
namespace App\Repositories\Drivers;
class ApiUserRepository implements UserRepository {
// Custom logic
}
Repository Interfaces Define interfaces for complex repositories to enforce contracts:
interface UserRepository {
public function getAdmins();
public function softDelete($id);
}
Repository Traits Share common logic across repositories using traits:
trait SoftDeletes {
public function softDelete($id) {
return $this->model->where('id', $id)->update(['deleted_at' => now()]);
}
}
Repository Events Extend event handling by publishing custom events:
event(new UserCreated($user));
How can I help you explore Laravel packages today?