All Projects → johnnyfreeman → Laravel Custom Relation

johnnyfreeman / Laravel Custom Relation

A custom relation for when stock relations aren't enough.

Labels

Projects that are alternatives of or similar to Laravel Custom Relation

Backup
MySQL Database backup package for Laravel
Stars: ✭ 66 (-4.35%)
Mutual labels:  laravel
Gupayment
GuPayment é um pacote para o Laravel que fornece uma interface para controlar assinaturas e pagamentos com o iugu.com
Stars: ✭ 67 (-2.9%)
Mutual labels:  laravel
Demo Laravel Json Api
Demo of JSON API integration with a Laravel Application
Stars: ✭ 68 (-1.45%)
Mutual labels:  laravel
Laravel.ru
Please use https://github.com/LaravelRUS/laravel.su instead
Stars: ✭ 66 (-4.35%)
Mutual labels:  laravel
Laravel Remember Uploads
Laravel Middleware and helper for remembering file uploads during validation redirects
Stars: ✭ 67 (-2.9%)
Mutual labels:  laravel
Chat Demo
Demo Application for https://github.com/musonza/chat/
Stars: ✭ 67 (-2.9%)
Mutual labels:  laravel
Groups
A Laravel 5 user groups package
Stars: ✭ 66 (-4.35%)
Mutual labels:  laravel
Laravel Botscout
Block malicious scripts using botscout.com protection for your laravel app
Stars: ✭ 69 (+0%)
Mutual labels:  laravel
Dreamfactory
DreamFactory API Management Platform
Stars: ✭ 1,148 (+1563.77%)
Mutual labels:  laravel
Laravel Mentions
End-to-end mentions in Laravel 5.
Stars: ✭ 68 (-1.45%)
Mutual labels:  laravel
Laravel Philips Hue
Laravel Philips Hue package to control your lights with remote support
Stars: ✭ 67 (-2.9%)
Mutual labels:  laravel
Lolibrary
👗The Lolita Fashion Library 👒
Stars: ✭ 67 (-2.9%)
Mutual labels:  laravel
Laravel Ecommerce
AvoRed an Open Source Laravel Shopping Cart
Stars: ✭ 1,151 (+1568.12%)
Mutual labels:  laravel
Laravel Restful Api Starter
Build a RESTful API with Laravel and MongoDB
Stars: ✭ 66 (-4.35%)
Mutual labels:  laravel
Phpstorm Laravel Live Templates
Laravel Live Templates for PhpStorm
Stars: ✭ 1,157 (+1576.81%)
Mutual labels:  laravel
Prequel
Prequel for Laravel. Clear and concise database management.
Stars: ✭ 1,141 (+1553.62%)
Mutual labels:  laravel
Ansible Provisioning Tywin
Generate your Ansible provisioning for Symfony2, Laravel and Node.js projects
Stars: ✭ 67 (-2.9%)
Mutual labels:  laravel
Attendant
Laravel Valet GUI
Stars: ✭ 69 (+0%)
Mutual labels:  laravel
Laravel Shopping Cart
Laravel shopping cart package
Stars: ✭ 69 (+0%)
Mutual labels:  laravel
Laravel Api Boilerplate Jwt
A Laravel 5.8 API Boilerplate to create a ready-to-use REST API in seconds.
Stars: ✭ 1,155 (+1573.91%)
Mutual labels:  laravel

This repo was a bit of a science experiment to find a solution to this issue. I now believe a better to handle custom relations is to create a new class possibly extending one of the existing classes.

Laravel Custom Relation

A custom relation for when stock relations aren't enough.

Use this if...

  • None of the stock Relations fit the bill. (BelongsToManyThrough, etc)

Installation

The recommended way to install is with composer:

composer require johnnyfreeman/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.)

class User
{
    public function roles() {
        return $this->belongsToMany(Role::class);
    }
}
class Role
{
    public function users() {
        return $this->belongsToMany(User::class);
    }

    public function permissions() {
        return $this->belongsToMany(Permission::class);
    }
}
class Permission
{
    public function roles() {
        return $this->belongsToMany(Role::class);
    }
}

What if you wanted to get all the Permissions for a User, or all the Users 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.

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', $relation->getKeys($models));
            }
        );
    }
}
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', $relation->getKeys($models));
            }
        );
    }
}

You could now do all the normal stuff for relations without having to query in-between relations first.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].