Skip to content

Instantly share code, notes, and snippets.

@ctf0
Last active September 13, 2023 14:25
  • Star 20 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ctf0/874e276b8d30e961bb9f359eac956988 to your computer and use it in GitHub Desktop.

under taggable model

<?php

use Illuminate\Database\Eloquent\Relations\MorphPivot;

class Taggable extends MorphPivot
{
    protected $table = 'taggables';

    /* -------------------------------------------------------------------------- */
    /*                                  RELATIONS                                 */
    /* -------------------------------------------------------------------------- */

    public function tag()
    {
        return $this->belongsTo(Tag::class);
    }

    public function related()
    {
        return $this->morphTo(__FUNCTION__, 'taggable_type', 'taggable_id');
    }
}

under tag model

<?php

class Tag extends Model
{
    protected $with = ['taggables.related'];
    
    /* -------------------------------------------------------------------------- */
    /*                                  RELATIONS                                 */
    /* -------------------------------------------------------------------------- */

    public function taggables()
    {
        return $this->hasMany(Taggable::class);
    }
    
    /* -------------------------------------------------------------------------- */
    /*                                  ACCESSORS                                 */
    /* -------------------------------------------------------------------------- */

    public function getRelatedModelsAttribute()
    {
        return $this->taggables->groupBy('taggable_type');
    }
}

under the related model

<?php

public function tags()
{
    return $this->morphToMany(Tag::class, 'taggable')
                ->using(Taggable::class);
}

now use it like

Tag::first()->related_models;
@ctf0
Copy link
Author

ctf0 commented Jul 27, 2020

use MorphPivot instead of Model according to docs so we can have model events ex.

/**
* Bootstrap the model and its traits.
*
* @return void
*/
public static function booted)
{
  static::saving(function ($model) {
      // ...
  });
}

@ctf0
Copy link
Author

ctf0 commented Jul 30, 2020

update getRelatedModelsAttribute to only groupBy so the eager load works correctly/efficiently. so we dont make a db request for each tag to find its related models.

instead now you will find your model under the group value->related

@rostockahoi
Copy link

Nice one, thanks a lot @ctf0

@joseangelcrn
Copy link

@ctf0 Thank you so much. It work very nice ! Im going to fork this one.

@SvetoslavStefanov
Copy link

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment