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

arafatdev/laravel-repository

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require arafatdev/laravel-repository
    

    Publish the config (optional):

    php artisan vendor:publish --provider="ArafatDev\Repository\RepositoryServiceProvider" --tag="config"
    
  2. 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)
  3. 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'));
    }
    

Key Files to Review

  • config/repository.php: Configuration for repository paths, stubs, and defaults.
  • app/Providers/RepositoryServiceProvider.php: Service binding (auto-registered by the package).

Implementation Patterns

Core Workflow

  1. 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.
  2. 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).

  3. 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']);
    
  4. Custom Queries: Extend the trait or override methods in the Eloquent class:

    public function activeUsers() {
        return $this->model->where('active', true)->get();
    }
    
  5. 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();
    }
    
  6. Transactions: Wrap repository calls in transactions:

    DB::transaction(function () {
        $this->userRepository->create(['name' => 'John']);
        $this->postRepository->create(['user_id' => 1, 'title' => 'Hello']);
    });
    

Integration Tips

  • API Resources: Pair repositories with API resources for consistent JSON responses.
    return new UserResource($this->userRepository->find($id));
    
  • Form Requests: Validate input in form requests before passing to repositories.
  • Events: Dispatch events after repository operations (e.g., created, updated).
  • Testing: Mock repositories in tests:
    $this->mock(App\Repositories\UserRepository::class)->shouldReceive('find')->andReturn($user);
    

Gotchas and Tips

Pitfalls

  1. Auto-Binding Conflicts:

    • If you manually bind a repository interface to a different implementation, the package’s auto-binding may override it. Disable auto-binding in config/repository.php:
      'auto_bind' => false,
      
  2. Trait Method Overrides:

    • Overriding methods in *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;
      }
      
  3. Model Not Found:

    • The find() method throws ModelNotFoundException by default. Handle it in your controller:
      try {
          $user = $this->userRepository->find($id);
      } catch (ModelNotFoundException $e) {
          abort(404);
      }
      
  4. Mass Assignment:

    • The create() and update() methods use $model->fill() by default, which respects $fillable. Ensure your model’s $fillable is correctly set or use $model->forceFill().
  5. Stub Customization:

    • Published stubs are stored in resources/stubs/repository. Modify them before generating new repositories:
      php artisan vendor:publish --provider="ArafatDev\Repository\RepositoryServiceProvider" --tag="stubs"
      

Debugging

  1. Check Bindings: Use Tinker to verify repository bindings:

    php artisan tinker
    >>> \Illuminate\Support\Facades\BindingResolver::getInstance()->getBindings();
    
  2. Log Queries: Enable Laravel’s query logging to debug repository queries:

    DB::enableQueryLog();
    $this->userRepository->all();
    dd(DB::getQueryLog());
    
  3. Stub Paths: If stubs aren’t generating correctly, verify the stubs_path in config/repository.php:

    'stubs_path' => resource_path('stubs/repository'),
    

Extension Points

  1. 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.

  2. 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);
    }
    
  3. Repository Events: Listen for repository events (e.g., repository.created) to trigger side effects:

    event(new UserCreated($user));
    
  4. Caching: Cache repository results for performance:

    public function all() {
        return Cache::remember('users.all', now()->addHours(1), function () {
            return $this->model->all();
        });
    }
    
  5. 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);
    }
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor