A package to implement repository pattern for laravel models

Overview

Laravel Model UUID

A simple package to use Repository Pattern approach for laravel models .

Repository pattern

Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer. Microsoft

Installation

Require the package using composer:

composer require touhidurabir/laravel-model-repository

To publish the config file:

php artisan vendor:publish --provider="Touhidurabir\ModelRepository\ModelRepositoryServiceProvider" --tag=config

Command and Configuration

To use this package, you need to have repository class bound to laravel model class . This package includes a command that make it easy to to create repository classes from command line . to create a new repository class, run the following command

php artisan make:repository UserRepository --model=User

The above command will create a new repository UserRepository class in App\Repositories path . the --model option to define which laravel model class to target for this repositoty class . The content of UserRepository will look like

namespace App\Repositories;

use Touhidurabir\ModelRepository\BaseRepository;
use App\Models\User;

class UserRepository extends BaseRepository {

	/**
     * Constructor to bind model to repo
     *
     * @param  object<App\Models\User> $user
     * @return void
     */
    public function __construct(User $user) {

        $this->model = $user;

        $this->modelClass = get_class($user);
    }

}

This package by default assume all models are located in path App\Models and use the path App\Repositories to store the repository classes. But also possible to provide custom repositories class path and different model class path . for example

php artisan make:reposity App\\SomeOtherPath\\UserRepository --model=App\\OtherModelPath\\User

The above command will try to store the repository class to path App\SomeOtherPath and will create a directory named SomeOtherPath if not already exists. Will also try to resolve model path/namespace from App\OtherModelPath .

Check the config file after publishing at the config/model-repository.php to see the default settings configurations .

It is also possible to replace an existing repository file via the command when passing the flag --replace

php artisan make:repository UserRepository --model=User --replace

The above command will replace the already exiting UserRepository.php at the given path with newly generated one.

Be ery carefull of the replacing ability as if your repository class contains any custom code, that will be fully replaced with a newly generated file and those custom changes will be lost.

Usage

The best way to use the repository classes via Dependency Injection through the controller classes . for example :

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;

class UserController extends Controller {

    /**
     * The resource repository instance
     *
     * @var mixed<object{\App\Repositories\UserRepository}|null>
     */
    protected $userRepository;

	/**
     * create a new controller instance
     *
     * @param  \App\Repositories\UserRepository         $userRepository
     * @return void
     */
    public function __construct(UserRepository $userRepository) {

        $this->userRepository = $userRepository;
    }
}

And in that way one can already get a fully qualified user repository class . Also to manually initiated :

namespace App\Http\Controllers;

use App\Models\User;
use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
...

$userRepository = new UserRepository(new User);

Or through static constructor

$userRepository = UserRepository::withModel(new User);

The repository class will have following features/abilities .

Create

To create a new model record, just call the create method on repositoty class and pass the data attributes as :

$this->userRepository->create([
    ...
]);

Update

To update a existing model record, call the update method of the repository class . the update method will require 2 params , the data attributes and the model redored primary key value or an exiting model instance .

To update with primary key for user with primary key of id with value 10

$primaryKeyValue = 10;

$this->userRepository->update([
    ...
], $primaryKeyValue);

or To update the already retrived model record :

$user; // the already retrived model record instance

$this->userRepository->update([
    ...
], $user);

Find

To find a model record, use the find method of the repository class

$this->userRepository->find(1); // find the id(primary key) of 1
$this->userRepository->find([1,2,3]); // find the id(primary key) of 1,2 and 3

The find method can also work with array where it will use those as AND WHERE query and return the first record that match

$this->userRepository->find(['email' => '[email protected]']);

By passing the optional relations array as the second argument to find method will load the relations along with model record

$this->userRepository->find(1, ['profile']); // find the id(primary key) of 1
$this->userRepository->find([1,2,3], ['profile']); // find the id(primary key) of 1,2 and 3

The thrid agument is a optional boolen which is by default set to false . By setting it to true, it will thorw the \Illuminate\Database\Eloquent\ModelNotFoundException when a model record not found .

$this->userRepository->find(1, ['profile'],  true); // find the id(primary key) of 1
$this->userRepository->find([1,2,3], [], true); // find the id(primary key) of 1,2 and 3

All Records

To get back all records, use the all method of repository class

$this->userRepository->all();

Delete

To Delete a model record, use the delete method of repository class

$this->userRepository->delete(1);

The delete method can wrok with model instance or the same kind of argument passed to the repository class find method .

$this->userRepository->delete($user); // delete the alredt retrived $user model instance
$this->userRepository->delete(1); // delete user id of 1
$this->userRepository->delete([1,2,3]); // delete user id of 1,2 and 3
$this->userRepository->delete(['email' => '[email protected]']); // delete user with email of [email protected]

The delete method also check for the SoftDelete feature , that is if the model is using the Illuminate\Database\Eloquent\SoftDeletes trait, the it will do the soft delete of given model records.

Force Delete

To Force Delete a model record, use the forceDelete method of repository class

$this->userRepository->forceDelete(1);

The delete method can wrok with model instance or the same kind of argument passed to the repository class find method .

$this->userRepository->forceDelete($user); // delete the alredt retrived $user model instance
$this->userRepository->forceDelete(1); // delete user id of 1
$this->userRepository->forceDelete([1,2,3]); // delete user id of 1,2 and 3
$this->userRepository->forceDelete(['email' => '[email protected]']); // delete user with email of [email protected]

The delete method also check for the SoftDelete feature, that is regardless of the model is using the Illuminate\Database\Eloquent\SoftDeletes trait, the it will remove those records from DB.

Restore

To Restore a model record that has soft deleted, use the forceDelete method of repository class

$this->userRepository->restore(1);

The restore will only works for those models that use the SoftDeletes feature . It try to use the restore on the model that do not have SoftDeletes implemented, it will throw an exception.

The restore method can wrok with model instance or array of model primary keys .

$this->userRepository->restore($user); // restore the already retrived $user model instance
$this->userRepository->restore(1); // restore user id of 1
$this->userRepository->restore([1,2,3]); // restore user id of 1,2 and 3test

Other Features

Get Model

As this package does not handle all of the features of Eloquent and if any other Eloquent method need to use to build complex query, we need the model instance . to get the model instance

$this->userRepository->getModel();

Also to set/update the model later

$this->userRepository->setModel(new User);
$this->userRepository->setModel($user);

Model Sanitizer

The BaseRepository class includes a model sanitizer that will automatically sanitize passed array attributes on model record create/update . Here sanatize means it will remove any element from the data array to match with the model table schema while at the same time respecting model $fillable and $hidden properties .

The implementation of these methods are as such

/**
 * Sanitize data list to model fillables
 *
 * @param  array   $data
 * @return array
 */
public function sanitizeToModelFillable(array $data) {

    $classModel   = $this->model->getModel();
    $fillable     = $classModel->getFillable();

    $fillables = ! empty($fillable) 
                    ? $fillable 
                    : array_diff(
                        array_diff(
                            Schema::getColumnListing($classModel->getTable()), 
                            $classModel->getGuarded()
                        ), 
                        $classModel->getHidden()
                    );

    return array_intersect_key($data, array_flip($fillables));
}

So even if extra details passed, it will be ignored or some columns passed that in the $fillable or $hidden list.

$user = $this->userRepository->create([
    'name' => 'User Name',
    'email' => '[email protected]',
    'password' => Hash::make('password'),
    'date_of_birth' => '1990-12-08' // This date_of_birth column not present in users table
]);

The above code will run without any issue while a simple model create method will throw exception .

$user = $this->userRepository->create($request->validated());

$profile = $this->profileRepository->create($request->validated());

This become very useful when in one single controller method do need to push data to multiple model table

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

You might also like...
Laminas\Console is a component to design and implement console applications in PHP.

laminas-console This package is abandoned and will receive no further development! We recommend using laminas/laminas-cli. Laminas\Console is a compon

Filament Plugin to help implement Cloudflare turnstile into your forms.
Filament Plugin to help implement Cloudflare turnstile into your forms.

Filament Turnstile Filament Turnstile, is a plugin to help you implement the Cloudflare turnstile. This plugin uses Laravel Turnstile Behind the scene

Laravel Design Pattern Generator (api generator)
Laravel Design Pattern Generator (api generator)

Laravel Design Pattern Generator (api generator) you can create your restful api easily by using this library and you can filter, sort and include elo

Laravel specification pattern

Laravel specification pattern Filter an Illuminate collection with specifications. Installation You can install the package via composer: composer req

A straightforward implementation of the Circuit Breaker pattern for Laravel 9

Laravel Circuit Breaker A straightforward implementation of the Circuit Breaker pattern for Laravel Framework 9 (using Memcached). Installation You ca

A lightweight domain event pattern implementation for Doctrine2.
A lightweight domain event pattern implementation for Doctrine2.

Knp Rad Domain Event A lightweight domain event pattern implementation for Doctrine2. Official maintainers: @Einenlum Installation With composer : $ c

Twig-based PatternEngine for Pattern Lab.

Twig PatternEngine for Pattern Lab The Twig PatternEngine allows you to use Twig as the template language for Pattern Lab PHP. Once the PatternEngine

States allows you to create PHP classes following the State Pattern in PHP.

States allows you to create PHP classes following the State Pattern in PHP. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements and this improve maintainability and workflows writing.

Laravel-Mediable is a package for easily uploading and attaching media files to models with Laravel 5.

Laravel-Mediable Laravel-Mediable is a package for easily uploading and attaching media files to models with Laravel. Features Filesystem-driven appro

Comments
  • Not working for me

    Not working for me

    When i run command to make repository i got:

    Exception Arise During Task Execution Exception : mkdir(): No such file or directory - C:\work\projects\aurum\vendor\laravel\framework\src\Illuminate\Filesystem\Filesystem.php at line 600

    opened by Grzyb9k 3
Releases(1.1.3)
Owner
null
Database Repository / PHP Repository / Laravel Repository

Database Repository / PHP Repository / Laravel Repository Installation Use following command to add this package to composer development requirement.

Bakery 6 Dec 21, 2022
🖖Repository Pattern in Laravel. The package allows to filter by request out-of-the-box, as well as to integrate customized criteria and any kind of filters.

Repository Repository Pattern in Laravel. The package allows to filter by request out-of-the-box, as well as to integrate customized criteria and any

Awes.io 160 Dec 26, 2022
Need some filters? This package is based on the Repository Design Pattern to let you create specific queries easily.

DevMakerLab/Laravel-Filters Need some filters? This package is based on the Repository Design Pattern to let you create specific queries easily. Insta

DevMakerLab 19 Feb 20, 2022
Cascading deletes for Eloquent models that implement soft deletes

Cascading soft deletes for the Laravel PHP Framework Introduction In scenarios when you delete a parent record - say for example a blog post - you may

Michael Dyrynda 767 Jan 6, 2023
Repository Pattern implementation for Laravel

This is a Simple Repository Pattern implementation for Laravel Projects and an easily way to build Eloquent queries from API requests.

Ephraïm SEDDOR 1 Nov 22, 2021
Fast and simple implementation of a REST API based on the Laravel Framework, Repository Pattern, Eloquent Resources, Translatability, and Swagger.

Laravel Headless What about? This allows a fast and simple implementation of a REST API based on the Laravel Framework, Repository Pattern, Eloquent R

Julien SCHMITT 6 Dec 30, 2022
Vandar Cashier is a Laravel package that allows you to seamlessly implement IPG and Direct Debit on your application

Vandar Cashier is a Laravel package that provides you with a seamless integration with Vandar services. Take a look at Vandar Documentation for more i

Vandar 11 Dec 14, 2022
laravel package help you to implement geographical calculation, with several algorithms that help you deal with coordinates and distances.

Geographical Calculator Geographical Calculator was developed for laravel 5.8+ to help you to implement geographical calculation, with With several al

karam mustafa 342 Dec 31, 2022
Your users do not always report errors, LaraBug does. LaraBug is a simple to use and implement error tracker built for the Laravel framework.

Your users do not always report errors, LaraBug does. LaraBug is a simple to use and implement error tracker built for the Laravel framework. This rep

LaraBug 197 Dec 9, 2022
A Laravel 8 Project Implement with GraphQL With Sanctum APIs Authentications Which utilized in Any Frontend or Any Mobile Application Programs.

A Laravel 8 Project Implement with GraphQL With Sanctum APIs Authentications Which utilized in Any Frontend or Any Mobile Application Programs.

Vikas Ukani 3 Jan 6, 2022