Giter Club home page Giter Club logo

compoships's Introduction

Compoships

Compoships offers the ability to specify relationships based on two (or more) columns in Laravel's Eloquent ORM. The need to match multiple columns in the definition of an Eloquent relationship often arises when working with third party or pre existing schema/database.

The problem

Eloquent doesn't support composite keys. As a consequence, there is no way to define a relationship from one model to another by matching more than one column. Trying to use where clauses (like in the example below) won't work when eager loading the relationship because at the time the relationship is processed $this->team_id is null.

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function tasks()
    {
        //WON'T WORK WITH EAGER LOADING!!!
        return $this->hasMany(Task::class)->where('team_id', $this->team_id);
    }
}

Related discussions:

Installation

The recommended way to install Compoships is through Composer

$ composer require awobaz/compoships

Usage

Using the Awobaz\Compoships\Database\Eloquent\Model class

Simply make your model class derive from the Awobaz\Compoships\Database\Eloquent\Model base class. The Awobaz\Compoships\Database\Eloquent\Model extends the Eloquent base class without changing its core functionality.

Using the Awobaz\Compoships\Compoships trait

If for some reasons you can't derive your models from Awobaz\Compoships\Database\Eloquent\Model, you may take advantage of the Awobaz\Compoships\Compoships trait. Simply use the trait in your models.

Note: To define a multi-columns relationship from a model A to another model B, both models must either extend Awobaz\Compoships\Database\Eloquent\Model or use the Awobaz\Compoships\Compoships trait

Syntax

... and now we can define a relationship from a model A to another model B by matching two or more columns (by passing an array of columns instead of a string).

namespace App;

use Illuminate\Database\Eloquent\Model;

class A extends Model
{
    use \Awobaz\Compoships\Compoships;
    
    public function b()
    {
        return $this->hasMany('B', ['foreignKey1', 'foreignKey2'], ['localKey1', 'localKey2']);
    }
}

We can use the same syntax to define the inverse of the relationship:

namespace App;

use Illuminate\Database\Eloquent\Model;

class B extends Model
{
    use \Awobaz\Compoships\Compoships;
    
    public function a()
    {
        return $this->belongsTo('A', ['foreignKey1', 'foreignKey2'], ['ownerKey1', 'ownerKey2']);
    }
}

Factories

Chances are that you may need factories for your Compoships models. If so, you will provably need to use Factory methods to create relationship models. For example, by using the ->has() method. Just use the Awobaz\Compoships\Database\Eloquent\Factories\ComposhipsFactory trait in your factory classes to be able to use relationships correctly.

Example

As an example, let's pretend we have a task list with categories, managed by several teams of users where:

  • a task belongs to a category
  • a task is assigned to a team
  • a team has many users
  • a user belongs to one team
  • a user is responsible for one category of tasks

The user responsible for a particular task is the user currently in charge for the category inside the team.

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use \Awobaz\Compoships\Compoships;
    
    public function tasks()
    {
        return $this->hasMany(Task::class, ['team_id', 'category_id'], ['team_id', 'category_id']);
    }
}

Again, same syntax to define the inverse of the relationship:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    use \Awobaz\Compoships\Compoships;
    
    public function user()
    {
        return $this->belongsTo(User::class, ['team_id', 'category_id'], ['team_id', 'category_id']);
    }
}

Supported relationships

Compoships only supports the following Laravel's Eloquent relationships:

  • hasOne
  • HasMany
  • belongsTo

Also please note that while nullable columns are supported by Compoships, relationships with only null values are not currently possible.

Support for nullable columns in 2.x

Version 2.x brings support for nullable columns. The results may now be different than on version 1.x when a column is null on a relationship, so we bumped the version to 2.x, as this might be a breaking change.

Disclaimer

Compoships doesn't bring support for composite keys in Laravel's Eloquent. This package only offers the ability to specify relationships based on more than one column. In a Laravel project, it's recommended for all models' tables to have a single primary key. But there are situations where you'll need to match many columns in the definition of a relationship even when your models' tables have a single primary key.

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Unit Tests

To run unit tests you have to use PHPUnit

Install compoships repository

git clone https://github.com/topclaudy/compoships.git
cd compoships
composer install

Run PHPUnit

./vendor/bin/phpunit

Authors

Support This Project

Buy Me a Coffee via Paypal

Sponsored by

  • Awobaz - Web/Mobile agency based in Montreal, Canada

License

Compoships is licensed under the MIT License.

compoships's People

Contributors

axelitus avatar bramus avatar christopheb avatar didac-adria avatar erikn69 avatar fmangelsdorf avatar hms5232 avatar isclopezm avatar leo108 avatar lxshadowxl avatar mdemblani avatar mpyw avatar pedrofmj avatar ragingdave avatar slydave avatar stefket avatar topclaudy avatar wojo1206 avatar y4my4my4m avatar yurii-github avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.