Installation:
composer require bosnadev/repositories:0.*
Publish the config (optional):
php artisan vendor:publish --provider="Bosnadev\Repositories\RepositoriesServiceProvider"
Define a Repository:
Create a repository class extending Bosnadev\Repositories\Eloquent\Repository and implement model():
namespace App\Repositories;
use App\Models\User;
use Bosnadev\Repositories\Eloquent\Repository;
class UserRepository extends Repository
{
public function model()
{
return User::class;
}
}
Register in Service Provider:
Bind the repository in AppServiceProvider:
$this->app->bind(
\App\Repositories\UserRepository::class,
function ($app) {
return new \App\Repositories\UserRepository(new \App\Models\User);
}
);
First Use Case: Inject the repository into a controller/service and use built-in methods:
$users = $this->userRepository->all();
$user = $this->userRepository->find(1);
CRUD Operations: Use built-in methods for common operations:
$this->userRepository->create(['name' => 'John']);
$this->userRepository->update(1, ['name' => 'Jane']);
$this->userRepository->delete(1);
Query Scoping: Chain methods for complex queries:
$activeUsers = $this->userRepository->scopeQuery(function ($query) {
return $query->where('active', true);
})->get();
Pagination:
$users = $this->userRepository->paginate(10);
Eager Loading:
$users = $this->userRepository->with('posts')->find(1);
Dependency Injection: Prefer constructor injection for repositories:
public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}
Service Layer: Use repositories in a service layer to decouple business logic from controllers.
Custom Methods: Extend repositories with domain-specific methods:
public function findByEmail($email)
{
return $this->scopeQuery(function ($query) use ($email) {
return $query->where('email', $email);
})->first();
}
Events: Trigger events post-create/update/delete:
$this->userRepository->create(['name' => 'John'], true); // Fires events
Model Binding:
Forgetting to bind the repository in the service provider will result in ClassNotFoundException.
Model Method Conflict:
Overriding model() incorrectly (e.g., returning an instance instead of a class name) will cause errors:
// Wrong:
public function model() { return new User; }
// Correct:
public function model() { return User::class; }
Query Scope Overrides:
Accidentally overriding scopeQuery() can break default query behavior.
Event Handling:
Events are disabled by default for create(), update(), and delete(). Pass true as the second argument to enable:
$this->userRepository->create($data, true);
Query Logging:
Enable query logging in config/repositories.php:
'logging' => true,
Logs will appear in Laravel's default log channels.
Repository Methods:
Use dd($this->userRepository->getMethodList()) to inspect available methods dynamically.
Default Scope:
Configure default scopes in config/repositories.php:
'default_scopes' => [
\App\Scopes\ActiveScope::class,
],
Model Events: Customize event names in the config:
'events' => [
'created' => 'user.created',
'updated' => 'user.updated',
],
Custom Scopes: Create reusable query scopes:
namespace App\Scopes;
use Bosnadev\Repositories\Contracts\Repository as RepositoryContract;
class ActiveScope implements \Bosnadev\Repositories\Contracts\Scope
{
public function apply(RepositoryContract $repository, $model)
{
return $model->where('active', true);
}
}
Repository Interfaces: Define interfaces for better type-hinting and testing:
interface UserRepositoryInterface {
public function findByEmail($email);
}
Repository Traits: Share common logic across repositories:
trait SoftDeletesTrait {
public function softDelete($id) {
return $this->update($id, ['deleted_at' => now()]);
}
}
Repository Decorators: Decorate repositories for cross-cutting concerns (e.g., logging, caching):
class LoggingRepositoryDecorator implements \Bosnadev\Repositories\Contracts\Repository
{
protected $repository;
public function __construct(UserRepository $repository) {
$this->repository = $repository;
}
public function create(array $attributes, $fireEvents = false)
{
\Log::info('Creating user', $attributes);
return $this->repository->create($attributes, $fireEvents);
}
}
How can I help you explore Laravel packages today?