Reputation: 21
All polymorh examples I found are one to many if I get it correct. (Tag to Post / Video e.g) In my Case the parent class is multiple and the child class also. Therefore i set up the pivot table
Tables
Person
id
Venture
id
Capital
id
Estate
id
PIVOT TABLE
Revenues
emitter_id //ID of the revenue emitting class (Venture, Capital, Estate)
emitter_type // Class of the Emitter (App\Models\Venture App\Models\Estate)
receiver_id // Id of Receiver (Venture or Person)
receiver_type // type of Receiver (App\Models\Venture or App\Models\Person)
revenue
In the Estate Model i try this
public function revenuePersons()
{
// searched type, own type/id ,tabel own ID to search id
return $this->morphToMany(Person::class, 'emitter' ,'revenues' ,'emitter_id','receiver_id')
->withPivot('revenue');
}
One the Person Model
public function estaterevenues(){
// searched type, own type/id ,tabel own ID to search id
return $this->morphToMany(Estate::class, 'receiver' ,'revenues' ,'receiver_id','emitter_id')
->withPivot('revenue');
}
The Code works but in some cases i get additional relations back. So it seams the searched _type is not correctly considered.
So i started to implement a own database query function that gives me the Revenue Entry back. It works correctly.
Revenue Model
public function getRevenue($ownside, $emitter_id = Null, $emitter_type,$receiver_id=Null, $receiver_type ){
$revenue = DB::table('revenues')
->where('emitter_id', $emitter_id)
.....()->get()}
But I am not able to do something like
$persons->getRevenues
because a Relationship is expected as return value
So if anyone has an idea how to do that correctly I would be very happy. Or some other best practices for this many to many approach.
The second Question is how to get all revenue receiver at once. Instead of
$estate->revenuepersons
$estate->revenueventures
Have something like
$estate->revenues //that list both, Ventures and Persons
Upvotes: 1
Views: 104
Reputation: 476
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
/**
* Get all of the posts that are assigned this tag.
*/
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
}
$post = Post::find(1);
dd($post->tags);
$video = Video::find(1);
dd($video->tags);
$tag = Tag::find(1);
dd($tag->posts);
$tag = Tag::find(1);
dd($tag->videos);
posts table migration:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
videos table migration:
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
tags table migration:
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
taggables table migration:
Schema::create('taggables', function (Blueprint $table) {
$table->integer("tag_id");
$table->integer("taggable_id");
$table->string("taggable_type");
});
Upvotes: 1