test
test

Reputation: 18200

Laravel 5.5 - Polymorphic relationships

Let's say I have four tables (models) in Laravel:

User.php

id - integer
name - string

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'token_id'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function embeds()
    {
        return $this->hasManyThrough('App\Post', 'App\Role');
    }
}

UserRoles.php

id - integer
user_id - integer
role_id - integer

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class UserRoles extends Pivot
{
    protected $guarded = [];

    public function role()
    {
        return $this->belongsTo(Role::class);
    }

    public function user()
    {
        return $this->belongsToMany(User::class, 'user_id');
    }
}

Role.php

id - integer
name - string

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    /**
     * Don't auto-apply mass assignment protection.
     *
     * @var array
     */
    protected $guarded = [];

    public function roles()
    {
        return $this->belongsToMany(UserRoles::class);
    }
}

Post.php

id - integer
title - string
body - text
role_id - integer

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * Don't auto-apply mass assignment protection.
     *
     * @var array
     */
    protected $guarded = [];
}

As you can see, a UserRoles is a pivot table to connect Users with Roles. And Posts can only be associated with one role (tech spec req).

How would make the relationships in Eloquent make it so I can have a user get every single Post they can see through the Roles they are assigned?

I have revised looking through the Laravel Relationships documentation and I have seen Many-to-Many polymorphic relationships but it seems I keep getting: SQLSTATE[42S02]: Base table or view not found: 1146 Table or some sort.

What am I doing wrong?

Upvotes: 0

Views: 263

Answers (1)

Hamoud
Hamoud

Reputation: 1929

Well, a pivot table does need a model. You need four tables and three Models.

You almost got the tables right. Just rename the UserRole table to role_user to follow Laravel convention.

The role_user table is derived from the alphabetical order of the related model names, and contains the user_id and role_id columns.

And here is how you should set up the models:

// User.php

    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }

    public function posts()
    {
        return $this->hasManyThrough(Post::class, Role::class);
    }

// Role.php

    public function users()
    {
        return $this->belongsToMany(User::class);
    }


    public function posts()
    {
        return $this->hasMany(Post::class);
    }

Upvotes: 1

Related Questions