aerojun
aerojun

Reputation: 1256

Many To Many (Polymorphic) using the same model with different types

I have these 3 tables in the database: Database

I'm using Many To Many (Polymorphic) Eloquent relationship to connect the Models. The problem is that the Creadores table can be of type artista or autor in the Creaciones table. Is it possible to tell Eloquent when to use artista or autor?

It works if I extend the Creador Model into 2 other Models: Artista and Autor. But when I want to show all the creaciones of a creador using the Creador Model, it's not possible because the Polymorphic relationship was created with the extended models.

Libro Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use ChrisKonnertz\BBCode\BBCode;

class Libro extends Model
{
    protected $table = 'Libros';

    // Return all the artists of the book
    public function artistas()
    {
        return $this->morphedByMany('App\Creador', 'creador', 'creaciones');
    }

    // Return all the authors of the book
    public function autores()
    {
        return $this->morphedByMany('App\Creador', 'creador', 'creaciones');
    }
}

Creador Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Creador extends Model
{
    protected $table = 'creators';

    // Return all the books where author
    public function autorLibros()
    {
        return $this->morphToMany('App\Libro', 'creador', 'creaciones');
    }

    // Return all the books where artist
    public function artistaLibros()
    {
        return $this->morphToMany('App\Libro', 'creador', 'creaciones');
    }
}

Upvotes: 1

Views: 788

Answers (2)

aerojun
aerojun

Reputation: 1256

Solved it the following way. Changed the relation from a Polymorphic Many to Many to a normal Many to Many, adding withPivot and wherePivot.

Creador Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Creador extends Model
{
    protected $table = 'creators';

    public function libros()
    {
        return $this->belongsToMany('App\Libro', 'creaciones')->withPivot('creador_type');
    }

    // All books as an Artist
    public function librosArtista()
    {
        return $this->libros()->wherePivot('creador_type', 1);
    }

    // All books as an Author
    public function librosAutor()
    {
        return $this->libros()->wherePivot('creador_type', 2);
    }
}

Libro Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use ChrisKonnertz\BBCode\BBCode;

class Libro extends Model
{
    protected $table = 'libros';

    public function creador()
    {
        return $this->belongsToMany('App\Creador', 'creaciones')->withPivot('creador_type');
    }

    // All book artists
    public function artistas()
    {
        return $this->creador()->wherePivot('creador_type', 1);
    }

    // All book authors
    public function autores()
    {
        return $this->creador()->wherePivot('creador_type', 2);
    }
}

And when creating a attaching a Creador to a Libro:

$libro->artistas()->attach( $creador, [
    'creador_type' => 1
]);

Upvotes: 0

Flame
Flame

Reputation: 7561

You might be better off just adding a type property to Creador with 'artista'/'autor' in it.

The polymorphic relationship can only take a single model. So your code would then become:

public function creadors()
{
    // Return a general relation for all 'creadores'.
    return $this->morphedByMany(App\Creador::class, 'creador', 'creaciones');
}

public function artistas()
{
    // Filter for 'artista's.
    return $this->creadors()->where('type', 'artista');
}

public function autores()
{
    // Filter for 'autor's.
    return $this->creadors()->where('type', 'autor');
}

Upvotes: 1

Related Questions