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

Eloquent Repository Laravel Package

orkhanahmadov/eloquent-repository

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require orkhanahmadov/eloquent-repository
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Orkhanahmadov\EloquentRepository\ServiceProvider"
    
  2. Define a Repository: Create a repository class (e.g., app/Repositories/UserRepository.php):

    namespace App\Repositories;
    
    use Orkhanahmadov\EloquentRepository\EloquentRepository;
    use App\Models\User;
    
    class UserRepository extends EloquentRepository
    {
        public function model()
        {
            return User::class;
        }
    }
    
  3. First Use Case: Inject the repository into a controller/service and use it like Eloquent:

    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(); // Equivalent to User::all()
            return response()->json($users);
        }
    }
    
  4. Key Files to Review:

    • config/eloquent-repository.php (for customizations).
    • app/Repositories/ (your repository classes).
    • Orkhanahmadov\EloquentRepository\EloquentRepository (base class).

Implementation Patterns

Core Workflows

  1. Basic CRUD Operations:

    // Create
    $user = $this->userRepository->create(['name' => 'John', 'email' => 'john@example.com']);
    
    // Read
    $user = $this->userRepository->find(1);
    $users = $this->userRepository->all();
    
    // Update
    $user = $this->userRepository->update(1, ['name' => 'Jane']);
    
    // Delete
    $this->userRepository->delete(1);
    
  2. Query Scoping:

    // Scope a query (e.g., active users)
    $activeUsers = $this->userRepository->scopeQuery(function ($query) {
        return $query->where('is_active', true);
    })->all();
    
    // Or use named scopes (if defined in the model)
    $activeUsers = $this->userRepository->scopeActive()->all();
    
  3. Eager Loading:

    $users = $this->userRepository->with(['posts', 'roles'])->get();
    
  4. Pagination:

    $users = $this->userRepository->paginate(10);
    
  5. Transactions:

    $this->userRepository->transaction(function ($repository) {
        $repository->create(['name' => 'Alice']);
        $repository->create(['name' 'Bob']);
    });
    

Integration Tips

  1. Dependency Injection: Bind repositories in AppServiceProvider for global access:

    public function register()
    {
        $this->app->bind(
            \App\Repositories\UserRepository::class,
            function ($app) {
                return new \App\Repositories\UserRepository(new \App\Models\User);
            }
        );
    }
    
  2. Service Layer: Use repositories in a service layer to decouple business logic from controllers:

    class UserService
    {
        protected $userRepository;
    
        public function __construct(UserRepository $userRepository)
        {
            $this->userRepository = $userRepository;
        }
    
        public function registerUser(array $data)
        {
            return $this->userRepository->create($data);
        }
    }
    
  3. API Resources: Combine with Laravel's API Resources for consistent JSON responses:

    $users = $this->userRepository->all();
    return UserResource::collection($users);
    
  4. Events and Observers: Trigger model events via repositories:

    $this->userRepository->create($data, ['fireEvents' => true]);
    
  5. Caching: Cache repository results using Laravel's cache:

    $users = $this->userRepository->remember(60, function () {
        return $this->userRepository->all();
    });
    

Gotchas and Tips

Pitfalls

  1. Model Binding:

    • Ensure the model() method in your repository returns the fully qualified class name of the Eloquent model (e.g., App\Models\User).
    • Gotcha: Forgetting this will throw Class 'User' not found errors.
  2. Query Builder vs. Eloquent:

    • The package wraps Eloquent methods, so raw query builder methods (e.g., selectRaw) may not work as expected. Use Eloquent's fluent methods instead:
      // Works
      $this->userRepository->select(['id', 'name'])->get();
      
      // May fail or behave unexpectedly
      $this->userRepository->selectRaw('id, name')->get();
      
  3. Mass Assignment:

    • By default, repositories respect the model's $fillable or $guarded properties. If you need to bypass this, use:
      $this->userRepository->create($data, ['fillable' => true]);
      
  4. Performance with Complex Queries:

    • Avoid chaining multiple scopes or eager loads in a single repository call. Break them into smaller, reusable methods:
      // Bad: Too many eager loads
      $this->userRepository->with(['posts', 'roles', 'comments'])->get();
      
      // Good: Split into smaller queries
      $users = $this->userRepository->all();
      $users->load(['posts', 'roles']);
      
  5. Transactions:

    • The transaction method requires a closure that accepts the repository instance. Forgetting to pass the repository to the closure will result in no transaction:
      // Wrong: Repository not passed to closure
      $this->userRepository->transaction(function () {
          $this->userRepository->create(...); // No transaction!
      });
      
      // Correct
      $this->userRepository->transaction(function ($repository) {
          $repository->create(...);
      });
      

Debugging Tips

  1. Enable Query Logging: Add this to AppServiceProvider to log all repository queries:

    public function boot()
    {
        \DB::enableQueryLog();
    }
    

    Then inspect queries via:

    \DB::getQueryLog();
    
  2. Check for Soft Deletes: If using soft deletes, ensure your queries account for it:

    $this->userRepository->withTrashed()->get(); // Include soft-deleted records
    
  3. Validate Repository Methods: Override methods in your repository to add custom logic or logging:

    public function find($id)
    {
        \Log::debug("Finding user with ID: {$id}");
        return parent::find($id);
    }
    

Extension Points

  1. Custom Scopes: Add reusable scopes to your repository:

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

    Use them like:

    $this->userRepository->scopeActive()->get();
    
  2. Repository Events: Listen for repository events (e.g., creating, created) by binding to the model's events:

    \App\Models\User::created(function ($user) {
        \Log::info("User created: {$user->id}");
    });
    
  3. Dynamic Attributes: Extend the repository to handle dynamic attributes or relationships:

    public function getFullName($id)
    {
        $user = $this->find($id);
        return "{$user->first_name} {$user->last_name}";
    }
    
  4. Repository Interfaces: Define interfaces for your repositories to enforce contracts:

    interface UserRepositoryInterface
    {
        public function findByEmail($email);
    }
    

    Then implement them in your repository:

    class UserRepository extends EloquentRepository implements UserRepositoryInterface
    {
        public function findByEmail($email)
        {
            return $this->scopeQuery(function ($query) use ($email) {
                return $query->where('email', $email);
            })->first();
        }
    }
    
  5. Repository Factories: Use repository factories to dynamically create repositories based on conditions:

    class RepositoryFactory
    {
        public static function make($modelClass)
        {
            $repositoryClass = "App\\Repositories\\" . class_basename($modelClass) . "Repository";
            return new $repositoryClass(new $modelClass);
        }
    }
    
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