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

Repositories Laravel Package

reb3r/repositories

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require bosnadev/repositories:0.*
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Bosnadev\Repositories\RepositoriesServiceProvider"
    
  2. Define a Repository: Create a repository class extending Bosnadev\Repositories\Eloquent\Repository and implement the model() method:

    namespace App\Repositories;
    
    use Bosnadev\Repositories\Eloquent\Repository;
    use App\Models\User;
    
    class UserRepository extends Repository
    {
        public function model()
        {
            return User::class;
        }
    }
    
  3. 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(new \App\Models\User);
        }
    );
    
  4. First Use Case: Inject the repository into a controller or 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();
            return view('users.index', compact('users'));
        }
    }
    

Implementation Patterns

Core Workflows

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

    $users = $userRepository->all();
    $user = $userRepository->find(1);
    $userRepository->create(['name' => 'John']);
    
  2. Query Scoping: Chain Eloquent query methods:

    $activeUsers = $userRepository->scopeQuery(function ($query) {
        return $query->where('active', true);
    })->all();
    
  3. Dependency Injection: Always inject repositories via constructor (not new):

    public function __construct(UserRepository $userRepository) { ... }
    
  4. Repository Interfaces: Define interfaces for repositories to enforce contracts:

    interface UserRepositoryInterface
    {
        public function getByEmail(string $email);
    }
    

    Implement them in your repository:

    class UserRepository extends Repository implements UserRepositoryInterface
    {
        public function getByEmail(string $email)
        {
            return $this->model->where('email', $email)->first();
        }
    }
    
  5. Event Handling: Trigger events via repository methods:

    $userRepository->create(['name' => 'John'], true); // Fires `created` event
    

Integration Tips

  1. Laravel Scout: Extend the repository for search functionality:

    class UserRepository extends Repository
    {
        public function search($query)
        {
            return $this->model->search($query)->get();
        }
    }
    
  2. API Resources: Use repositories to fetch data for API responses:

    $users = $userRepository->all();
    return UserResource::collection($users);
    
  3. Testing: Mock repositories in tests:

    $mock = Mockery::mock(UserRepository::class);
    $mock->shouldReceive('find')->andReturn($user);
    $this->app->instance(UserRepository::class, $mock);
    
  4. Caching: Cache repository results:

    $users = Cache::remember('users.all', 60, function () {
        return $userRepository->all();
    });
    
  5. Transactions: Wrap repository operations in transactions:

    DB::transaction(function () use ($userRepository) {
        $userRepository->create(['name' => 'John']);
        $userRepository->create(['name' => 'Jane']);
    });
    

Gotchas and Tips

Pitfalls

  1. Model Binding: Forgetting to implement model() will throw BadMethodCallException. Always verify:

    public function model()
    {
        return User::class; // Must return a valid Eloquent model class
    }
    
  2. Lazy Loading: Avoid eager loading in repositories to prevent N+1 queries. Use with() explicitly:

    $users = $userRepository->with('posts')->find(1); // Correct
    $users = $userRepository->all(); // May trigger N+1 if not careful
    
  3. Mass Assignment: Repository create()/update() uses $model->fill() by default. Override to customize:

    public function create(array $attributes)
    {
        return parent::create($attributes, ['name', 'email']); // Whitelist
    }
    
  4. Soft Deletes: Ensure your model uses SoftDeletes trait if relying on delete():

    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class User extends Model
    {
        use SoftDeletes;
    }
    
  5. Service Provider Binding: Binding repositories manually can lead to singleton issues. Use Laravel's container properly:

    $this->app->singleton(UserRepository::class, function ($app) {
        return new UserRepository(new User);
    });
    

Debugging

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

    DB::enableQueryLog();
    $users = $userRepository->all();
    dd(DB::getQueryLog());
    
  2. Model Events: Listen for model events to debug repository behavior:

    User::created(function ($user) {
        Log::info('User created:', ['user' => $user]);
    });
    
  3. Repository Methods: Override repository methods to add logging:

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

Extension Points

  1. Custom Query Scopes: Add reusable scopes to the repository:

    class UserRepository extends Repository
    {
        public function scopeActive($query)
        {
            return $query->where('active', true);
        }
    }
    

    Usage:

    $activeUsers = $userRepository->scopeActive()->get();
    
  2. Repository Events: Dispatch events from repository methods:

    public function create(array $attributes)
    {
        $model = parent::create($attributes);
        event(new UserCreated($model));
        return $model;
    }
    
  3. Repository Decorators: Decorate repositories to add cross-cutting concerns:

    class LoggingUserRepository implements UserRepositoryInterface
    {
        protected $userRepository;
    
        public function __construct(UserRepository $userRepository)
        {
            $this->userRepository = $userRepository;
        }
    
        public function find($id)
        {
            Log::info("Finding user ID: {$id}");
            return $this->userRepository->find($id);
        }
    }
    
  4. Dynamic Attributes: Extend repositories to handle dynamic attributes:

    public function update(array $attributes, $id)
    {
        $model = $this->find($id);
        $model->update($attributes + ['updated_at' => now()]);
        return $model;
    }
    
  5. Repository Factories: Use factories to create repositories with default configurations:

    $userRepository = app()->makeWith(UserRepository::class, [
        'model' => new User,
        'cache' => true
    ]);
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui