Search code examples
phplaravellaravel-permission

Extending the Spatie Role Model but use a different database table


What I need to do is extend all of the functionality of the Spatie permissions package Role model, but use a different table for the derived model.

Right now I have a model SubscriptionPackage that I want to emulate the behavior of a Role such that it can be assigned permissions and in turn this model can be assigned to users. But I wanna keep the Role model intact too.

I have tried extending Yes, but when I create a new SubscriptionPackage, the new record is created in the roles tables instead of subscription_packages table despite specifying the table in my derived Model. As shown below

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\Permission; // This extends from Spatie\Permission\Models\Permission
use Spatie\Permission\Models\Role as SpatieRole;



class SubscriptionPackage extends SpatieRole
{
    //
    protected $guarded = ['id'];

    protected $table = 'subscription_packages';


    /**
     * The permissions that belong to the package.
     */
    public function packagePermissions()
    {
        return $this->belongsToMany(Permission::class);
    }

}

With the code above I expect when I create a new SubscriptionPackage, the record should be inserted into the subscription_packages table but in this case it goes to the roles table. Any pointers on how to go about this will be highly appreciated.


Solution

  • If you have a look at the Role source code you will this inside the __construct method:

    public function __construct(array $attributes = [])
        {
            $attributes['guard_name'] = $attributes['guard_name'] ?? config('auth.defaults.guard');
            parent::__construct($attributes);
            $this->setTable(config('permission.table_names.roles')); // <-- HERE IS THE PROBLEM!
        }
    

    So, if you want that your SubscriptionPackage to write its records in the right table you have to override this behaviour like this:

    public function __construct(array $attributes = [])
        {
            parent::__construct($attributes)
    
            $this->setTable('your_table_name'); // <-- HERE THE SOLUTION!
        }