Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Repositories Laravel Package

rinvex/laravel-repositories

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require rinvex/laravel-repositories
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Rinvex\Repositories\RepositoriesServiceProvider"
    
  2. Define a Repository: Create a model (e.g., User) and its corresponding repository interface:

    // app/Repositories/Contracts/UserRepositoryInterface.php
    namespace App\Repositories\Contracts;
    use Rinvex\Repositories\Contracts\RepositoryInterface;
    
    interface UserRepositoryInterface extends RepositoryInterface
    {
        public function findByEmail(string $email);
    }
    
  3. Implement the Repository:

    // app/Repositories/Eloquent/UserRepository.php
    namespace App\Repositories\Eloquent;
    use App\Repositories\Contracts\UserRepositoryInterface;
    use Rinvex\Repositories\Eloquent\EloquentRepository;
    
    class UserRepository extends EloquentRepository implements UserRepositoryInterface
    {
        public function findByEmail(string $email)
        {
            return $this->scopeQuery(function ($query) use ($email) {
                return $query->where('email', $email);
            })->first();
        }
    }
    
  4. Bind the Repository: In a service provider (e.g., AppServiceProvider):

    $this->app->bind(
        \App\Repositories\Contracts\UserRepositoryInterface::class,
        \App\Repositories\Eloquent\UserRepository::class
    );
    
  5. First Use Case: Inject and use the repository in a controller:

    // app/Http/Controllers/UserController.php
    use App\Repositories\Contracts\UserRepositoryInterface;
    
    class UserController extends Controller
    {
        protected $userRepository;
    
        public function __construct(UserRepositoryInterface $userRepository)
        {
            $this->userRepository = $userRepository;
        }
    
        public function show($email)
        {
            $user = $this->userRepository->findByEmail($email);
            return view('user.show', compact('user'));
        }
    }
    

Implementation Patterns

Core Workflows

  1. CRUD Operations: Leverage built-in methods like all(), find(), create(), update(), and delete():

    $users = $this->userRepository->all();
    $user = $this->userRepository->find(1);
    $this->userRepository->create(['name' => 'John']);
    
  2. Custom Scopes: Use scopeQuery() to add reusable query constraints:

    public function scopeActive($query)
    {
        return $this->scopeQuery(function ($query) {
            return $query->where('active', true);
        });
    }
    

    Usage:

    $activeUsers = $this->userRepository->scopeActive()->get();
    
  3. Caching: Enable granular caching via config (config/repositories.php):

    'cache' => [
        'enabled' => true,
        'default' => 'file',
        'stores' => [
            'file' => [
                'driver' => 'file',
                'path' => storage_path('framework/cache/repositories'),
            ],
        ],
    ],
    

    Cache methods automatically (e.g., find(), all()).

  4. Transactions: Wrap operations in transactions:

    $this->userRepository->transaction(function () {
        $user = $this->userRepository->create(['name' => 'Alice']);
        $profile = $this->profileRepository->create(['user_id' => $user->id]);
    });
    

Integration Tips

  • Service Layer: Use repositories in a service layer to decouple business logic from controllers:

    // app/Services/UserService.php
    class UserService
    {
        protected $userRepository;
    
        public function __construct(UserRepositoryInterface $userRepository)
        {
            $this->userRepository = $userRepository;
        }
    
        public function register(array $data)
        {
            return $this->userRepository->create($data);
        }
    }
    
  • API Resources: Combine with Laravel's API Resources for clean JSON responses:

    // app/Http/Resources/UserResource.php
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
    

    Usage:

    return new UserResource($this->userRepository->find(1));
    
  • Events: Trigger events post-CRUD operations:

    $this->userRepository->created(function ($user) {
        event(new UserRegistered($user));
    });
    

Gotchas and Tips

Pitfalls

  1. Abandoned Package:

  2. Caching Overhead:

    • Granular caching can lead to stale data if not managed carefully. Use cache()->forget() or repository()->flushCache() to clear caches manually when needed.
    • Example:
      $this->userRepository->flushCache();
      
  3. Model Binding:

    • Ensure models are properly bound to repositories. Use the repository() helper or manually bind interfaces in the service container.
    • Example binding:
      $this->app->bind(\App\Repositories\Contracts\UserRepositoryInterface::class,
          \App\Repositories\Eloquent\UserRepository::class);
      
  4. Laravel Version Mismatch:

    • The dev-develop branch targets Laravel 5.5+. For newer versions, expect potential compatibility issues (e.g., query builder syntax, dependency conflicts).
    • Test thoroughly in a staging environment.
  5. Performance with Large Datasets:

    • Avoid caching all() or get() for large datasets, as it may load excessive data into memory.
    • Use pagination or cursors instead:
      $users = $this->userRepository->paginate(10);
      

Debugging

  1. Query Logging: Enable Laravel's query logging to debug repository queries:

    DB::enableQueryLog();
    $this->userRepository->all();
    dd(DB::getQueryLog());
    
  2. Cache Debugging: Check cache hits/misses by inspecting the cache store:

    $cache = Cache::store('file');
    $cache->get('repository:User:all');
    
  3. Repository Events: Listen for repository events to debug lifecycle hooks:

    event(new Creating($model));
    event(new Created($model));
    

Extension Points

  1. Custom Repository Classes: Extend Rinvex\Repositories\Eloquent\EloquentRepository to add shared logic:

    class BaseRepository extends EloquentRepository
    {
        public function softDelete($id)
        {
            return $this->find($id)->delete();
        }
    }
    
  2. Dynamic Scopes: Use traits to add dynamic scopes across repositories:

    trait Searchable
    {
        public function scopeSearch($query, $term)
        {
            return $this->scopeQuery(function ($query) use ($term) {
                return $query->where('name', 'like', "%{$term}%");
            });
        }
    }
    
  3. Repository Decorators: Decorate repositories to add cross-cutting concerns (e.g., logging, auditing):

    class LoggingRepositoryDecorator implements UserRepositoryInterface
    {
        protected $repository;
    
        public function __construct(UserRepositoryInterface $repository)
        {
            $this->repository = $repository;
        }
    
        public function find($id)
        {
            Log::info("Finding user with ID: {$id}");
            return $this->repository->find($id);
        }
    }
    

    Bind the decorator in the service container:

    $this->app->bind(
        UserRepositoryInterface::class,
        function ($app) {
            return new LoggingRepositoryDecorator(
                $app->make(\App\Repositories\Eloquent\UserRepository::class)
            );
        }
    );
    
  4. Testing: Mock repositories in tests for isolation:

    $mock = Mockery::mock(UserRepositoryInterface::class);
    $mock->shouldReceive('find')->andReturn($user);
    $this->app->instance(UserRepositoryInterface::class, $mock);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope