Weave 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

Repository Laravel Package

rinvex/repository

Rinvex Repository is a Laravel package that implements the repository pattern with a powerful base repository: CRUD, validation, events, caching, and reusable query criteria, keeping your models clean and your data layer testable and swappable.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat rinvex/repository as a legacy but useful abstraction layer: install it, pin the exact version, and verify its Laravel/PHP constraints before committing. It is archived, so for a new long-lived application, fork it or wrap it behind your own contracts.

composer require rinvex/repository

Create a repository by extending BaseRepository and setting the model plus a unique, stable repository ID:

namespace App\Repositories;

use App\Models\Post;
use Rinvex\Repository\Repositories\BaseRepository;

class PostRepository extends BaseRepository
{
    protected $model = Post::class;

    protected $repositoryId = 'app.posts';

    protected $cacheKeys = ['id', 'slug'];
    protected $cacheMinutes = 60;
}

Bind it in a service provider if you want constructor injection and contracts:

$this->app->bind(PostRepository::class, PostRepository::class);

First practical use case: read-heavy listing with eager loading and pagination.

final class ListPublishedPosts
{
    public function __construct(private PostRepository $posts)
    {
    }

    public function handle()
    {
        return $this->posts
            ->where('status', 'published')
            ->with('author')
            ->orderBy('published_at', 'desc')
            ->paginate(15);
    }
}

Look first at vendor/rinvex/repository/src/Repositories/BaseRepository.php and the repository contract. Those files tell you the exact CRUD, query, and cache-reset methods available in your pinned version. Also inspect any Rinvex package that uses the same repository base; those are the most reliable in-the-wild examples.

Implementation Patterns

Inject repositories into actions, services, or controllers rather than instantiating them directly. For larger applications, define a contract and bind it:

interface PostRepositoryContract
{
}

class PostRepository extends BaseRepository implements PostRepositoryContract
{
    protected $model = Post::class;
    protected $repositoryId = 'app.posts';
}

$this->app->bind(PostRepositoryContract::class, PostRepository::class);

Use the base repository for common reads and writes:

$post = $this->posts->find($id);
$post = $this->posts->findBy('slug', $slug);
$posts = $this->posts->where('status', 'published')->get();
$posts = $this->posts->with('comments')->paginate(20);
$post = $this->posts->create($attributes);
$this->posts->update($id, $attributes);
$this->posts->delete($id);

Keep domain-specific queries inside the repository instead of leaking query fragments across controllers:

public function published(): self
{
    return $this->where('status', 'published');
}

public function findBySlug(string $slug)
{
    return $this->findBy('slug', $slug);
}

For caching, start small. Enable per-repository caching only for stable, read-heavy lookup data:

protected $cacheEnabled = true;
protected $cacheMinutes = 30;
protected $cacheKeys = ['id', 'slug'];

After any write path, verify that the repository cache is invalidated. If your version does not invalidate automatically for a custom bulk update, call the repository’s cache reset/flush method explicitly. Wrap multi-step writes in DB::transaction():

DB::transaction(function () use ($attributes) {
    $post = $this->posts->create($attributes);
    $this->posts->flushCache(); // confirm exact method name in your version
});

Use eager loading at query time to avoid N+1 problems:

return $this->posts
    ->with(['author', 'comments'])
    ->where('status', 'published')
    ->paginate(20);

For multi-tenant applications, make the repository ID and cache prefix tenant-aware:

protected $repositoryId = 'app.tenant.42.posts';

In tests, disable caching or use a fake repository implementation. Use RefreshDatabase for integration tests and bind the contract to a mock or in-memory fake when testing application services. For reporting queries, dashboards, and complex filtering, prefer dedicated query objects or custom repository methods returning arrays; do not force every SQL shape through the generic repository API.

Gotchas and Tips

The biggest risk is cache invalidation. Writes made directly through Eloquent bypass the repository and can leave stale cache entries. Bulk updates, imports, queued jobs, and artisan commands must all clear the relevant repository cache if they modify data the repository has cached. Use short TTLs for volatile data.

Keep $repositoryId unique and stable. Changing it orphans old cache entries, and reusing it across models or tenants can cause cache collisions. Include the application, model, and tenant where relevant.

Make $cacheKeys match the columns you actually query by. If you look up records by uuid but only cache id, the cache key generation may not behave as expected. Include every unique lookup column used by common read paths.

Be careful with cached paginated or filtered results. Page number, per-page count, filters, and ordering all affect the result. If the package does not include those arguments in its cache key, avoid caching those queries or override the cache key generation in your repository.

Check the cache store. Tag-based invalidation generally requires Redis or Memcached; file and database cache stores may not support it. If the package relies on tags, either use a compatible store or disable caching.

Debug stale data by disabling repository caching first, then inspect the generated cache keys and repository prefix in your cache store. Enable Laravel query logging to confirm whether the repository is hitting the database or returning cached results.

Extension points are straightforward: override getCacheKey, cache reset logic, or model resolution in a subclass; add domain methods; bind contracts; and decorate repositories with application services. Keep repositories focused on one aggregate. If a repository starts accumulating dozens of unrelated query methods, split it or move complex reads into query objects.

Because the package is abandoned, pin the exact version in composer.json, commit composer.lock, and test upgrades against your target Laravel version. For long-lived projects, maintain a fork under your own namespace and treat the original package as a starting point rather than an actively maintained dependency.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo