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 Repository Laravel Package

salehhashemi/laravel-repository

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require salehhashemi/laravel-repository
    

    Publish the config (optional):

    php artisan vendor:publish --provider="SalehHashemi\LaravelRepository\LaravelRepositoryServiceProvider"
    
  2. First Use Case: Define a repository for a model (e.g., User):

    php artisan make:repository User
    

    This generates:

    • Repositories/UserRepository.php (base repository)
    • Repositories/UserRepositoryEloquent.php (Eloquent implementation)
  3. Basic Usage:

    // In a controller or service
    $users = app(\App\Repositories\UserRepository::class)->all();
    $user = app(\App\Repositories\UserRepository::class)->find(1);
    

Where to Look First

  • Repository Contracts: app/Repositories/Contracts/ – Define interfaces for your repositories.
  • Base Classes: app/Repositories/ – Extend BaseRepository or BaseRepositoryEloquent.
  • Criteria: app/Repositories/Criteria/ – Define reusable query filters (e.g., ActiveUsers, Search).

Implementation Patterns

Core Workflows

  1. Repository Layer:

    • Separation of Concerns: Move all database logic to repositories. Controllers/services only call repository methods.
      // Controller
      public function index(UserRepository $repository)
      {
          $users = $repository->scope(['active'])->paginate();
          return view('users.index', compact('users'));
      }
      
    • Dependency Injection: Bind repositories in AppServiceProvider:
      $this->app->bind(
          \App\Repositories\Contracts\UserRepository::class,
          \App\Repositories\UserRepositoryEloquent::class
      );
      
  2. Criteria-Based Filtering:

    • Define criteria (e.g., ActiveUsers):
      namespace App\Repositories\Criteria;
      
      use SalehHashemi\LaravelRepository\Criteria\Criteria;
      
      class ActiveUsers extends Criteria
      {
          public function apply($model)
          {
              return $model->where('is_active', true);
          }
      }
      
    • Apply in repository:
      $activeUsers = $this->scope(['active'])->get();
      
    • Or chain multiple criteria:
      $users = $this->scope(['active', 'search:name=John'])->paginate();
      
  3. Presenter Layer:

    • Transform models to DTOs/presenters:
      $user = $this->presenter()->make($userModel);
      
    • Define presenters in app/Repositories/Presenters/.
  4. Events and Observers:

    • Trigger events from repositories:
      $this->create($data); // Fires `creating`, `created`, etc.
      
    • Attach observers to repositories (not models) for centralized logic.

Integration Tips

  • API Resources: Combine with Laravel’s API Resources for consistent JSON responses.
    $users = $this->presenter()->collection($this->all());
    
  • Testing: Mock repositories in tests:
    $this->mock(UserRepository::class)->shouldReceive('find')->andReturn($user);
    
  • Transactions: Use repository()->transaction() for multi-repository operations:
    $this->repository()->transaction(function () {
        $this->userRepository->create($userData);
        $this->orderRepository->create($orderData);
    });
    

Gotchas and Tips

Pitfalls

  1. N+1 Queries:

    • Avoid eager-loading in repositories unless necessary. Use with() sparingly.
    • Prefer presenter()->make() with lazy-loaded relationships for APIs.
  2. Over-Abstraction:

    • Don’t move business logic into repositories. Keep them thin (e.g., no validation).
    • Use services for complex workflows that span multiple repositories.
  3. Criteria Performance:

    • Complex criteria chains can lead to slow queries. Test with DB::enableQueryLog().
    • Cache frequent criteria results:
      $this->scope(['active'])->remember(60)->get();
      
  4. Model Binding:

    • Ensure repositories are bound after models are bootstrapped (e.g., in AppServiceProvider).

Debugging

  • Query Logs: Enable Laravel’s query logging to inspect repository-generated queries:
    DB::enableQueryLog();
    $users = $repository->all();
    dd(DB::getQueryLog());
    
  • Criteria Debugging: Add dd($this->getModel()) in a criteria’s apply() method to inspect the query builder.

Extension Points

  1. Custom Repository Methods:

    • Add methods to your repository class:
      public function findByEmail($email)
      {
          return $this->findWhere(['email' => $email])->first();
      }
      
    • Use findWhere, findOneWhere, or findWhereIn for common queries.
  2. Dynamic Scopes:

    • Extend BaseRepository to add dynamic scopes:
      public function scopeTrashed($query)
      {
          return $query->whereNull('deleted_at');
      }
      
    • Use in controllers:
      $trashedUsers = $repository->trashed()->get();
      
  3. Repository Events:

    • Listen for repository events (e.g., repository.creating):
      Event::listen('repository.creating', function ($repository, $attributes) {
          $attributes['created_by'] = auth()->id();
          return $attributes;
      });
      
  4. Testing Repositories:

    • Use RepositoryServiceProvider for testing:
      $this->app->register(\SalehHashemi\LaravelRepository\RepositoryServiceProvider::class);
      
    • Mock repositories with Mockery or Laravel’s built-in mocking.

Config Quirks

  • Default Model: The model key in config/repository.php sets the default model for repositories. Override per-repository if needed.
  • Presenter Path: Customize presenter_path to change where presenters are stored (default: app/Repositories/Presenters/).
  • Criteria Namespace: Ensure criteria classes are in App\Repositories\Criteria or update the criteria_namespace config.
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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