Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A laravel package that use the full power of relations to create automatic joins and perform advanced filtering

License

NotificationsYou must be signed in to change notification settings

railken/eloquent-mapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Actions Status

A laravel package that use the full power of relations to create automatic joins and perform advanced filtering.

Given for e.g. two modelsOffice andEmployee, you can transform a string like this"employees.name ct 'Mario Rossi' or employees.name ct 'Giacomo'" into a sql query like this

select offices.*from`offices`left join`employees`as`employees`on`employees`.`office_id`=`offices`.`id`where (`employees`.`name`like ?or`employees`.`name`like ?)

Functions:

Requirements

PHP 8.1 and laravel 8

Installation

You can install it viaComposer by typing the following command:

composer require railken/eloquent-mapper

Usage

In order to use this library you need a map.

Create a new class wherever you want like the following example

app/Map.php

namespaceApp;useRailken\EloquentMapper\MapasBaseMap;class Mapextends BaseMap{/**     * Return an array of all models you want to map     *     * @return array     */publicfunctionmodels():array    {/** return [            \App\Models\User::class        ]; **/    }}

The methodmodels must return a list of all models. You can even add models that are in your vendor folder, regardless of the logic you use, you only have to return an array.

Railken\EloquentMapper\Map also has the mapping of relations and attributes based on the model, if you wish you can ovveride that functionality and write your own.Check source

These methods are invoked only when you call the commandartisan mapper:generate (see below) and the result will be cached in a file placed inbootstrap/cache/map.php.

This means you can perform whatever logic you want to retrieve all models (e.g. scanning files), so don't worry about caching.

Important: In order to be detected, all relations must return the typeIlluminate\Database\Eloquent\Relations\Relation like this:

namespaceApp;useIlluminate\Database\Eloquent\Relations\BelongsTo;class Fooextends Model{/**     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo     */publicfunctionbar():BelongsTo    {return$this->belongsTo(Bar::class);    }}

Now it's time to register this class in any provider to override the default one.

app/Providers/AppServiceProvider.php

namespaceApp\Providers;useIlluminate\Support\ServiceProvider;useApp\Map;useRailken\EloquentMapper\Contracts\MapasMapContract;class AppServiceProviderextends ServiceProvider{/**     * @inherit     */publicfunctionregister()    {$this->app->bind(MapContract::class, Map::class);    }}

Artisan

There is only one command, and it'sartisan mapper:generate. This command will remap and recache so keep in mind that you have to execute it whanever you change your code models .

If you use models that are in your vendor folder, you could add this in yourcomposer.json to reload everytime the libreries are updated.

{"scripts": {"post-autoload-dump": ["@php artisan mapper:generate"        ]    }}

Filtering

Sow how the filtering actually works?

useRailken\EloquentMapper\Scopes\FilterScope;useRailken\EloquentMapper\With\WithCollection;useRailken\EloquentMapper\With\WithItem;useApp\Models\Foo;$foo =newFoo;$query =$foo->newQuery();$filter ="created_at >= 2019";$scope =newFilterScope;$scope->apply($query,$filter,newWithCollection([newWithItem('bar')]));

And that's it!$query is now filtered, ifFoo has any relationships you can use the dot notation and the filter will automatically perform the join. For e.g. ifFoo has a relationship calledtags and you want to retrieve allFoo with the tag namemyCustomTag simply usetag.name = 'myCustomTag'.

Here's thefull syntax

The third parameter is the eager loading option. You can of course use the dot notation as well and add subquery.For istance the following example rapresent a list of all authors that contains the nameMario and returns all of theirs books that have atag.name calledsci-fi.

useRailken\EloquentMapper\Scopes\FilterScope;useRailken\EloquentMapper\With\WithCollection;useRailken\EloquentMapper\With\WithItem;useRailken\EloquentMapper\Tests\Models\Author;$author =newAuthor;$query =$author->newQuery();$filter ="name ct 'Mario'";$scope =newFilterScope;$scope->apply($query,$filter,newWithCollection([newWithItem('books','tag.name eq "sci-fi"')]));

Joiner

This is an internal class used by theFilterScope to join the necessary relations before performing the filtering, but you can use it indipendently.see tests

Example - Setup

Let's continue with a real example, first the setup. We will use two models:Office andEmployee

app/Models/Office.php

namespaceApp\Models;useIlluminate\Database\Eloquent\Model;useIlluminate\Database\Eloquent\Relations\HasMany;class Officeextends Model{/**     * @var array     */public$fillable = ['name','description'    ];/**     * @return \Illuminate\Database\Eloquent\Relations\HasMany     */publicfunctionemployees():HasMany    {return$this->hasMany(Employee::class);    }}

app/Models/Employee.php

namespaceApp\Models;useIlluminate\Database\Eloquent\Model;useIlluminate\Database\Eloquent\Relations\BelongsTo;useApp\Models\Office;class Employeeextends Model{/**     * @var array     */public$fillable = ['name','description','office_id'    ];/**     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo     */publicfunctionoffice():BelongsTo    {return$this->belongsTo(Office::class);    }}

app/Map.php

namespaceApp;useRailken\EloquentMapper\MapasBaseMap;class Mapextends BaseMap{/**     * Return an array of all models you want to map     *     * @return array     */publicfunctionmodels():array    {return [            \App\Models\Employee::class,            \App\Models\Office::class        ];    }}

Example - Usage

Retrieve all offices that have employees with nameMario Rossi orGiacomo

useApp\Models\Office;useRailken\EloquentMapper\Scopes\FilterScope;$office =newOffice;$query =$office->newQuery();$filter ="employees.name ct 'Mario Rossi' or employees.name ct 'Giacomo'"$scope = new FilterScope();$scope->apply($query,$filter);echo$query->toSql();

Result:

select offices.*from`offices`left join`employees`as`employees`on`employees`.`office_id`=`offices`.`id`where (`employees`.`name`like ?or`employees`.`name`like ?)

About

A laravel package that use the full power of relations to create automatic joins and perform advanced filtering

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp