Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ardalanamini/laravel-custom-relation
Create your own custom relation for when stock relations aren't enough
https://github.com/ardalanamini/laravel-custom-relation
custom eloquent laravel relation relationship
Last synced: 19 days ago
JSON representation
Create your own custom relation for when stock relations aren't enough
- Host: GitHub
- URL: https://github.com/ardalanamini/laravel-custom-relation
- Owner: ardalanamini
- License: mit
- Created: 2018-01-03T09:14:46.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2023-09-16T15:27:28.000Z (about 1 year ago)
- Last Synced: 2024-10-06T20:42:07.642Z (about 1 month ago)
- Topics: custom, eloquent, laravel, relation, relationship
- Language: PHP
- Size: 10.7 KB
- Stars: 4
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Laravel Custom Relation
Create your own custom relation for when stock relations aren't enough
[TOC]
## Use this if...
* None of the stock Relations fit the bill. (BelongsToManyThrough, etc)
## Installation
The recommended way to install is with [composer](http://getcomposer.org/):
```shell
composer require ardalanamini/laravel-custom-relation
```## Example
Let's say we have 3 models:
- `User`
- `Role`
- `Permission`Let's also say `User` has a many-to-many relation with `Role`, and `Role` has a many-to-many relation with `Permission`.
So their models might look something like this. (I kept them brief on purpose.)
```php
class User {
public function roles() {
return $this->belongsToMany(Role::class);
}
}
``````php
class Role {
public function users() {
return $this->belongsToMany(User::class);
}public function permissions() {
return $this->belongsToMany(Permission::class);
}
}
``````php
class Permission {
public function roles() {
return $this->belongsToMany(Role::class);
}
}
```**What if you wanted to get all the `Permission`s for a `User`, or all the `User`s with a particular `Permission`?** There no stock Relation in Laravel to descibe this. What we need is a `BelongsToManyThrough` but no such thing exists in stock Laravel.
## Solution
First, make sure your models are using the `HasCustomRelations` trait. Then, define custom relations like this.
```php
use LaravelCustomRelation\HasCustomRelations;class User {
use HasCustomRelations;/**
* Get the related permissions
*
* @return Illuminate\Database\Eloquent\Relations\Relation
*/
public function permissions() {
return $this->custom(
Permission::class,// add constraints
function ($relation) {
$relation->getQuery()
// join the pivot table for permission and roles
->join('permission_role', 'permission_role.permission_id', '=', 'permissions.id')
// join the pivot table for users and roles
->join('role_user', 'role_user.role_id', '=', 'permission_role.role_id')
// for this user
->where('role_user.user_id', $this->id);
},// add eager constraints
function ($relation, $models) {
$relation->getQuery()->whereIn(
'role_user.user_id',
collect($models)->map(function ($value) {
return $value->getKey();
})->values()->unique()->sort()->all()
);
}
);
}
}
``````php
use LaravelCustomRelation\HasCustomRelations;class Permission {
use HasCustomRelations;/**
* Get the related users
*
* @return Illuminate\Database\Eloquent\Relations\Relation
*/
public function users() {
return $this->custom(
User::class,// constraints
function ($relation) {
$relation->getQuery()
// join the pivot table for users and roles
->join('role_user', 'role_user.user_id', '=', 'users.id')
// join the pivot table for permission and roles
->join('permission_role', 'permission_role.role_id', '=', 'role_user.role_id')
// for this permission
->where('permission_role.permission_id', $this->id);
},// eager constraints
function ($relation, $models) {
$relation->getQuery()->whereIn(
'permission_role.permission_id',
collect($models)->map(function ($value) {
return $value->getKey();
})->values()->unique()->sort()->all()
);
}
);
}
}
```You could now do all the normal stuff for relations without having to query in-between relations first.