Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ctf0/874e276b8d30e961bb9f359eac956988 to your computer and use it in GitHub Desktop.
Save ctf0/874e276b8d30e961bb9f359eac956988 to your computer and use it in GitHub Desktop.

under taggable model add

<?php

class Taggable extends Model
{
    protected $with = ['related'];

    public $timestamps = false;

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

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

    public function related()
    {
        return $this->morphTo();
    }
}

under tag model add

<?php

class Tag extends Model
{
    protected $with = ['taggables'];

    public $timestamps = false;

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

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

    public function getItemsAttribute()
    {
        return $this->taggables
            ->groupBy('taggable_type')
            ->map(function ($v, $k) {
                return app($k)->whereIn('id', $v->pluck('taggable_id'))->get();
            })->all();
    }
}

and now use it like

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

ctf0 commented Jul 27, 2020

update related method according to docs as with plain $this->morphTo() we would get null instead

@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