Laravel Many to Many Relationship on the same Model through a pivot table providing two-way association.
kingmaker/laravel-many-to-many-self-relationship is a Laravel package for laravel many to many relationship on the same model through a pivot table providing two-way association..
It currently has 18 GitHub stars and 111.830 downloads on Packagist (latest version 2.1.8).
Install it with composer require kingmaker/laravel-many-to-many-self-relationship.
Discover more Laravel packages by kingmaker
or browse all Laravel packages to compare alternatives.
Last updated
This package includes an extension to the belongsToMany Relationship of the Laravel
allowing two-way association between the same model with a single Entry on the pivot table.
The package can be installed via Composer.
composer install kingmaker/laravel-many-to-many-self-relationship
Include the HasBelongsToManySelfRelation trait in the Model class and
define the relation method as follows:
use Illuminate\Database\Eloquent\Model;
use Kingmaker\Illuminate\Eloquent\Relations\HasBelongsToManySelfRelation;
class Post extends Model {
use HasBelongsToManySelfRelation;
public function relatedPosts()
{
return $this->belongsToManySelf('related_posts', 'post1', 'post2');
}
}
It is that simple and has all the Methods available on the belongsToMany().
The Related Posts can be accessed like any normal relation.
$post = Post::first();
$post->relatedPosts; // returns Collection of Related Posts
This is an extension over the native
BelongsToManyclass provided by the Eloquent.
Consider there are 'posts' table and 'related_posts' table. The Post represent Post in the blog and it can have related posts similar to them.
posts:
| id | title | body |
+----+-------+------+
| 1 | a | ... |
| 2 | b | ... |
| 3 | c | ... |
| 4 | d | ... |
+----+-------+------+
related_posts:
| id | post1 | post2 |
+----+-------+-------+
| 1 | 1 | 3 |
| 2 | 1 | 4 |
| 3 | 2 | 1 |
| 4 | 2 | 3 |
| 5 | 3 | 4 |
| 6 | 4 | 2 |
+----+-------+-------+
The belongsToManySelf relation provides two-way association when calling the Relation.
Post::find(1)->relatedPosts; // returns Posts with id 2, 3, 4
Post::find(2)->relatedPosts; // returns Posts with id 1, 3, 4
Post::find(3)->relatedPosts; // returns Posts with id 1, 2, 4
Post::find(4)->relatedPosts; // returns Posts with id 1, 2, 3
There is a possibility for the returning of duplicate related object if the entities are related by 2rows on the Pivot table.
This two-way associated Many-to-Many relationship can be used in few peculiar situations. This relation doesn't suit all the Scenarios.
Consider a blog or shopping website, where we have post / product related to each other.
When the related Entity is matched via BelongsToMany relationship, the association of one Post/Product as related to
the other post/product, on fetching the relatedPost or relatedProduct from the first Object will yield the second,
but the inverse is not true (ie, getting first post/product as related post/product from the second)
In Social Media, the concept of Users being friended to one another can be easily achieved using this relation (not followers & following, just mutual friends). Once a Users add another User as friends, we can attach the User and doesn't need to care about the attachment of reverse while using this relationship.
Note: The Concept of followers and following has to use the Laravel's
BelongsToManyrelation. This relation is for friends like in Facebook.
The Message in a Chat application, where a message is directed from a User to another User. This relation lets you retrieve all the Users that have messaged a particular User.
Note: There may be possibility of duplicates in this case
The trait HasBelongsToManySelfRelation adds the method belongsToManySelf to your Model.
/**
* create the BelongsToManySelf relation on the same Model via a pivot table
*
* @param string $table Pivot table name
* @param string $pivotKey1 Pivot table foreign key 1
* @param string $pivotKey2 Pivot table foreign key 2
* @param string|null $relatedKey Related key on the parent table
* @param string|null $relation Relation name
* @return BelongsToManySelf
*/
public function belongsToManySelf(string $table, string $pivotKey1, string $pivotKey2, $relatedKey = null, $relation = null)
The BelongsToManySelf is a concrete/child/sub-class of the Eloquent BelongsToMany class.
So, All the methods available on the BelongsToMany is also available on this Relation.
The following Issues / Problems were found in this package or the underlying Database Engine.
has and whereHas constraint will not work in MySQL < v8.0.14(pivot_key1, pivot_key2) and (pivot_key2, pivot_key1)Contributions are always welcome!
Feel free to open Issues and submit Pull Requests