## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require littlebug/laravel-repository
Publish the config (optional):
php artisan vendor:publish --provider="Littlebug\Repository\RepositoryServiceProvider"
Define a Repository:
Create a repository class (e.g., app/Repositories/UserRepository.php):
namespace App\Repositories;
use Littlebug\Repository\EloquentRepository;
use App\Models\User;
class UserRepository extends EloquentRepository
{
public function model()
{
return User::class;
}
}
Register the Repository:
Bind the repository in a service provider (e.g., AppServiceProvider):
$this->app->bind(
\App\Repositories\UserRepository::class,
function ($app) {
return new \App\Repositories\UserRepository($app['db']);
}
);
First Use Case: Inject the repository into a controller/service and use it:
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: Leverage built-in methods like:
$user = $this->userRepository->find(1);
$users = $this->userRepository->all();
$this->userRepository->create(['name' => 'John']);
$this->userRepository->update(1, ['name' => 'Jane']);
$this->userRepository->delete(1);
Query Scoping:
Use scope* methods for reusable query constraints:
class UserRepository extends EloquentRepository
{
public function scopeActive($query)
{
return $query->where('active', true);
}
}
Call it via:
$activeUsers = $this->userRepository->scopeActive()->get();
Dependency Injection:
Bind repositories in AppServiceProvider or use Laravel's container:
$this->app->bind(
\App\Repositories\UserRepository::class,
function ($app) {
return new UserRepository($app->make('db'), $app->make('cache'));
}
);
Event Integration: Trigger events in repositories:
class UserRepository extends EloquentRepository
{
protected $observes = ['created', 'updated', 'deleted'];
public function create(array $attributes)
{
$model = parent::create($attributes);
event(new UserCreated($model));
return $model;
}
}
Transaction Handling: Wrap operations in transactions:
$this->userRepository->transaction(function ($repo) {
$repo->create(['name' => 'Alice']);
$repo->create(['name' 'Bob']);
});
Repository Interfaces:
Define interfaces for contracts (e.g., UserRepositoryInterface):
interface UserRepositoryInterface
{
public function findByEmail(string $email);
}
Implement in the repository:
class UserRepository extends EloquentRepository implements UserRepositoryInterface
{
public function findByEmail(string $email)
{
return $this->findWhere(['email' => $email])->first();
}
}
Caching: Cache repository results:
$this->userRepository->remember(3600, function () {
return $this->all();
});
API Resource Integration: Use repositories with API resources:
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
];
}
}
Fetch via repository:
return UserResource::collection($this->userRepository->all());
Repository Groups:
Group related repositories (e.g., AuthRepositoryGroup):
$this->app->bind(
\App\Repositories\AuthRepositoryGroup::class,
function ($app) {
return new AuthRepositoryGroup(
$app->make(UserRepository::class),
$app->make(RoleRepository::class)
);
}
);
Model Binding:
model() in the repository.public function model() to return the model class.trait UsesUserModel
{
public function model()
{
return User::class;
}
}
Query Builder vs. Eloquent:
DB facade and Eloquent queries in repositories.where(), orderBy()) for consistency.query() method to access the underlying query builder:
$query = $this->userRepository->query();
$query->whereRaw('...');
return $query->get();
Overriding Methods:
find()) without calling parent::method().parent:: to maintain default behavior:
public function find($id)
{
$model = parent::find($id);
// Custom logic
return $model;
}
Caching Conflicts:
rememberForever() with caution.tags for cache invalidation:
$this->userRepository->remember('users', 3600, function () {
return $this->all();
});
// Invalidate later:
Cache::forget('users');
Dependency Injection:
Query Logging:
Enable query logging in config/database.php:
'log' => true,
'log_queries' => true,
Check logs in storage/logs/laravel.log.
Repository Events:
$observes property is set and events are dispatched in the correct methods (e.g., creating, updating).Performance Bottlenecks:
toBase() to avoid eager loading unnecessary relations:
$user = $this->userRepository->find(1)->toBase();
Custom Repository Methods: Add domain-specific methods:
class UserRepository extends EloquentRepository
{
public function findByEmail(string $email)
{
return $this->findWhere(['email' => $email])->first();
}
public function countActive()
{
return $this->scopeActive()->count();
}
}
Repository Decorators: Decorate repositories for cross-cutting concerns (e.g., logging, auditing):
class LoggingUserRepository implements UserRepositoryInterface
{
protected $decorated;
public function __construct(UserRepository $decorated)
{
$this->decorated = $decorated;
}
public function find($id)
{
Log::info("Finding user {$id}");
return $this->decorated->find($id);
}
}
Repository Events: Extend event handling:
class UserRepository extends EloquentRepository
{
protected $dispatchesEvents = [
'creating' => UserCreating::class,
'created' => UserCreated::class,
'updating' => UserUpdating::class,
'updated' => UserUpdated::class,
'deleting' => UserDeleting::class,
'deleted' => UserDeleted::class,
];
}
Repository Testing: Mock repositories in tests:
$mock = Mockery::mock(UserRepository::class);
$mock->shouldReceive('find')->andReturn($user);
$this->app->instance(UserRepository::class, $mock);
How can I help you explore Laravel packages today?