0
votes

This is the error I am getting the at moment:

    Type error: Argument 1 passed to Illuminate\Database\Eloquent\Relations\BelongsToMany::save() 
must be an instance of Illuminate\Database\Eloquent\Model, 
integer given, 
called in /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php on line 814

The create user method, where I call the giveRole() method:

protected function create(array $data)
    {
        $user = User::create([
            'name'     => $data['name'],
            'email'    => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        // On registration user will be given the default role of user
        $user->giveRole();

        $verifyUser = VerifyUser::create([
            'user_id' => $user->id,
            'token'   => str_random(40)
        ]);

        Mail::to($user->email)->send(new VerifyMail($user));

        return $user;
    }

HasPermissionsTrait:

<?php

namespace App\App\Permissions;

use App\{Role, Permission};

/**
 *
 */
trait HasPermissionsTrait
{

    public function giveRole($role = 'user')
    {
        $role = \DB::table('roles')->where('name', '=', $role)->first();

        $this->roles()->saveMany([$role->id]);

        return $this;
    }

    public function givePermission(...$permissions)
    {
        $permissions = $this->getPermissions(\array_flatten($permissions));

        if($permissions === null)
            return $this;

        $this->permissions()->saveMany($permissions);

        return $this;
    }

    public function widrawPermission(...$permissions)
    {
        $permissions = $this->getPermissions(\array_flatten($permissions));

        $this->permissions()->detach($permissions);

        return $this;
    }

    public function updatePermissions(...$permissions)
    {
        $this->permissions()->detach();

        return $this->givePermission($permissions);
    }

    public function hasRole(...$roles)
    {
        foreach ($roles as $role) {

            if($this->roles->contains('name', $role))
                return true;

        }

        return false;
    }

    public function hasPermissionTo($permission)
    {
        return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
    }

    protected function hasPermission($permission)
    {
        return (bool) $this->permissions->where('name', $permission->name)->count();
    }

    protected function hasPermissionThroughRole($permission)
    {
        foreach ($permission->roles as $role) {
            if($this->role->contains($role))
                return true;
        }

        return false;
    }

    protected function getPermissions(array $permissions)
    {
        return Permissions::whereIn('name', $permissions)->get();
    }

    public function roles()
    {
         return $this->belongsToMany(Role::class, 'users_roles', 'user_id', 'role_id');
    }

    public function permissions()
    {
       return $this->belongsToMany(Permissions::class, 'users_permissions');
    }
}

Role model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    public function permissions()
    {
       return $this->belongsToMany(Permissions::class, 'roles_permissions');
    }

}

User model:

namespace App;

use App\App\Permissions\HasPermissionsTrait;

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

class User extends Authenticatable
{
    use Notifiable, HasPermissionsTrait;

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

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

    public function clinic()
    {
       return $this->hasOne(Clinic::class, 'owner_id');
    }

    public function files()
    {
       return $this->hasMany('App/Media');
    }

    public function verifyUser()
    {
        return $this->hasOne('App\VerifyUser');
    }

}

What am I doing wrong here?

1

1 Answers

0
votes

Have you tried passing in the role model instead of the id? Also, on a separate note, it looks as if you might as well just call save as you are not actually ever utilizing an array in this instance.

trait HasPermissionsTrait
{

    public function giveRole($role = 'user')
    {
        $role = \DB::table('roles')->where('name', '=', $role)->first();

        $this->roles()->saveMany([$role]);

        return $this;
    }

}

saveMany calls save:

public function saveMany($models, array $joinings = [])
{
    foreach ($models as $key => $model) {
        $this->save($model, (array) Arr::get($joinings, $key), false);
    }
    $this->touchIfTouching();
    return $models;
}

and save has typecasted Model, not int:

/**
 * Save a new model and attach it to the parent model.
 *
 * @param  \Illuminate\Database\Eloquent\Model  $model
 * @param  array  $joining
 * @param  bool   $touch
 * @return \Illuminate\Database\Eloquent\Model
 */
public function save(Model $model, array $joining = [], $touch = true)
{
    $model->save(['touch' => false]);
    $this->attach($model->getKey(), $joining, $touch);
    return $model;
}