Jeremy Layson
Jeremy Layson

Reputation: 53

Get all relationships in many-to-many polymorphic

I know that many-to-many polymorphic relationship is possible. However, the tutorials points me in a way that each tables will be in a separate relationship (function).

However, I need a way to create a many-to-many polymorphic relationship wherein I can fetch all of its relationships even if they're from multiple tables.

Example:

Log
->connected_tables (the model relationship)
--> [0] App\User
--> [1] App\User
--> [2] App\Transaction
--> [3] App\Item
--> [4] App\ShippingInformation

The pivot table is as follows:

$table->increments('id');
$table->integer('entity_id')->unsigned();
$table->string('entity_type');
$table->integer('loggable_id')->unsigned();
$table->string('loggable_type');

Then in my log model, I'm trying to fetch it as:

public function loggable()
{
    return $this->morphToMany('App\????', 'entity', 'activity_log_entity');
}

This is the part where I don't know what to put anymore.

Upvotes: 3

Views: 2316

Answers (2)

glupeksha
glupeksha

Reputation: 520

We can easily retrieve all the models in a relationship by creating a model for the pivot table. As example,

This is the example for many to many polymorphic relationship in Laravel Documentation.

posts
    id - integer
    name - string

videos
    id - integer
    name - string

tags
    id - integer
    name - string

taggables
    tag_id - integer
    taggable_id - integer
    taggable_type - string

We can create models 'App\Post','App\Video','App\Tag' and 'App\Taggable'. To retrieve all the models with a specific tag id we can use, "'App\Taggable'::where('tag_id',1)->get()".

Also for more ease, we can add the following function to the 'App\Tag' model.

public function taggables()
{
    return 'App\Taggable'::where('tag_id',$this->id)->get();
}

Upvotes: 1

Jeremy Layson
Jeremy Layson

Reputation: 53

I've found a work-around this problem. But I've got a small problem along with it.

First, in my log table, I put a hasMany relationship through my pivot and eagerloaded the "relatedTables"

public function logs()
{
    return $this->hasMany('App\LogPivot', 'entity_id')->with('relatedTables');
}

Then I created a model for the pivot and put this relationship

public function relatedTables()
{
    return $this->morphTo('loggable');
}

So this will fetch all of the pivots of a log, then each pivots will morph themselves into whatever they are pointed to.

The problem is that the pivot will be the first instead of the actual table. How can I "pluck" the actual table instead of the pivot?

App\LogPivot {#1251
  id: 2,
  entity_id: 573,
  entity_type: "log",
  loggable_id: 3,
  loggable_type: "user",
  created_at: null,
  updated_at: null,
  related_table: null,
  loggable: App\User {#1259
    id: 3,
    name: "Juan",
  },
},

I want to get the App\User straight on its relationship instead of LogPivot first

Upvotes: 1

Related Questions