Installation:
composer require arafatdev/laravel-repository
Publish the config (optional):
php artisan vendor:publish --provider="ArafatDev\Repository\RepositoryServiceProvider" --tag="config"
Generate a Repository:
php artisan make:repository PostRepository --model=Post
This creates:
app/Repositories/PostRepository.php (interface)app/Repositories/Eloquent/PostRepositoryEloquent.php (implementation)app/Repositories/Eloquent/PostRepositoryEloquentTrait.php (trait with CRUD methods)First Use Case: Inject the repository into a service/controller:
use App\Repositories\PostRepository;
use App\Repositories\Eloquent\PostRepositoryEloquent;
public function __construct(PostRepository $postRepository) {
$this->postRepository = $postRepository;
}
public function index() {
$posts = $this->postRepository->all();
return view('posts.index', compact('posts'));
}
config/repository.php: Configuration for repository paths, stubs, and defaults.app/Providers/RepositoryServiceProvider.php: Service binding (auto-registered by the package).Repository Generation: Use the Artisan command to scaffold repositories for new models:
php artisan make:repository UserRepository --model=User --with-migration
Flags:
--model: Specify the model class.--with-migration: Generate a migration if the model doesn’t exist.--force: Overwrite existing files.Dependency Injection:
Bind the repository interface to its Eloquent implementation in AppServiceProvider:
$this->app->bind(
App\Repositories\UserRepository::class,
App\Repositories\Eloquent\UserRepositoryEloquent::class
);
Or use the package’s auto-binding (enabled by default in config/repository.php).
CRUD Operations:
The generated *RepositoryEloquentTrait provides:
all(): Fetch all records.find($id): Find by ID.create(array $data): Create a record.update($id, array $data): Update a record.delete($id): Delete a record.
Example:$user = $this->userRepository->find(1);
$this->userRepository->update(1, ['name' => 'Updated Name']);
Custom Queries: Extend the trait or override methods in the Eloquent class:
public function activeUsers() {
return $this->model->where('active', true)->get();
}
Scopes: Use Laravel’s query scopes in the model and call them via the repository:
// In User model:
public function scopePublished($query) {
return $query->where('published', true);
}
// In UserRepositoryEloquent:
public function published() {
return $this->scopeQuery('published')->get();
}
Transactions: Wrap repository calls in transactions:
DB::transaction(function () {
$this->userRepository->create(['name' => 'John']);
$this->postRepository->create(['user_id' => 1, 'title' => 'Hello']);
});
return new UserResource($this->userRepository->find($id));
created, updated).$this->mock(App\Repositories\UserRepository::class)->shouldReceive('find')->andReturn($user);
Auto-Binding Conflicts:
config/repository.php:
'auto_bind' => false,
Trait Method Overrides:
*RepositoryEloquent must call parent::method() if extending the trait’s default behavior. Example:
public function find($id) {
$model = parent::find($id);
// Custom logic
return $model;
}
Model Not Found:
find() method throws ModelNotFoundException by default. Handle it in your controller:
try {
$user = $this->userRepository->find($id);
} catch (ModelNotFoundException $e) {
abort(404);
}
Mass Assignment:
create() and update() methods use $model->fill() by default, which respects $fillable. Ensure your model’s $fillable is correctly set or use $model->forceFill().Stub Customization:
resources/stubs/repository. Modify them before generating new repositories:
php artisan vendor:publish --provider="ArafatDev\Repository\RepositoryServiceProvider" --tag="stubs"
Check Bindings: Use Tinker to verify repository bindings:
php artisan tinker
>>> \Illuminate\Support\Facades\BindingResolver::getInstance()->getBindings();
Log Queries: Enable Laravel’s query logging to debug repository queries:
DB::enableQueryLog();
$this->userRepository->all();
dd(DB::getQueryLog());
Stub Paths:
If stubs aren’t generating correctly, verify the stubs_path in config/repository.php:
'stubs_path' => resource_path('stubs/repository'),
Custom Repository Types: Extend the package to support non-Eloquent repositories (e.g., API clients). Create a new trait and update the Artisan command’s stubs.
Global Scopes: Add global scopes to the repository’s model to apply them across all queries:
// In User model:
protected static function booted() {
static::addGlobalScope(new ActiveScope);
}
Repository Events:
Listen for repository events (e.g., repository.created) to trigger side effects:
event(new UserCreated($user));
Caching: Cache repository results for performance:
public function all() {
return Cache::remember('users.all', now()->addHours(1), function () {
return $this->model->all();
});
}
Soft Deletes: Enable soft deletes in the model and repository:
// In User model:
use SoftDeletes;
protected $dates = ['deleted_at'];
// In UserRepositoryEloquent:
public function find($id) {
return $this->model->withTrashed()->find($id);
}
How can I help you explore Laravel packages today?