Роли в Laravel не работают должным образом - PullRequest
1 голос
/ 09 июня 2019

Я сделал по книге роли для моей программы Laravel.Проблема возникает в одном конкретном случае, один из методов в пользовательской модели всегда «всплывающий» ... Независимо от того, что пользователь имеет для role_id, метод всегда показывает имя определенной роли, в данном случае «модератор».Не знаю, что с ним не так, или, по крайней мере, я его не вижу ...

Вот модель пользователя:

<?php

    namespace App;

    use Illuminate\Notifications\Notifiable;
    use Illuminate\Contracts\Auth\MustVerifyEmail;
    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',"avatar"
        ];

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

        /**
         * The attributes that should be cast to native types.
         *
         * @var array
         */
        protected $casts = [
            'email_verified_at' => 'datetime',
        ];

        public function rola(){
            return $this->belongsTo("App\Roles", "id");
        }

        public function posts(){
            return $this->hasMany("App\Post");
        }

        public function comments(){
            return $this->hasMany("App\Comment");
        }

        public function isAdmin()
        {//dd($user);

            return $this->rola()->where('role', 'administrator');
        }

        public function isModerator()
        {//dd($user);

            return $this->rola()->where('role', 'moderator');
        }

        public function isUser()
        {//dd($user);

            return $this->rola()->where('role', 'user');
        }

        public function isPeon()
        {//dd($user);

            return $this->rola()->where('role', 'peon');        
        }

}

Вот модель ролей:

<?php

    namespace App;

    use Illuminate\Database\Eloquent\Model;

    class Roles extends Model
    {
        public function rola(){
            return $this->hasMany("App\User", "role_id");
        }
    }

И, например, если просто отобразить в любом виде:

    {{auth()->user()->rola->id}} <br> // 2 <- correct
    {{auth()->user()->role_id}} // 3 <- this should be 2 also.

Вот изображение моей схемы БД: schema

Иизображение таблицы ролей: roles

По умолчанию, каждый раз, когда новый пользователь регистрируется, он автоматически получает роль "peon" с идентификатором 4. Возможно, я не уверен, где моя ошибкая чего-то не вижу ...

Edit1:

Вот ссылка на github repo для тех, кто хочет взять гусакна это.

Ответы [ 3 ]

3 голосов
/ 09 июня 2019

Чтобы улучшить ваше приложение, не используйте одну функцию для каждой вашей роли. Предположим, у вас есть 100 ролей в таблице ролей, с текущим кодом вам также понадобятся 100 функций, таких как isAdmin или isSomething.

Добавить что-то вроде этого:

    public function hasRole($roleName)
    {
        return $this->rola()->where('role', $roleName);
    }

    /**
    * Check if the user has any of the given roles.
    */
    public function hasAnyRole(array $roleNames)
    {
        $userRole = $this->rola;
        return in_array($userRole->name, $roleNames);
    }

Теперь вы можете проверить роли:

    $user->hasRole('admin'); //If the user has the admin role, returns true. Otherwise returns false.

Чтобы проверить роли в виде диска:

@if(Auth::check())
    @if(Auth::user()->hasRole('role-name') || Auth::user()->hasRoles('another-role-name'))
        //Your markup here
    @endif
@endif

И для нескольких ролей:

@if(Auth::check())
    @if(Auth::user()->hasAnyRoles(['role-name', 'another-role-name']))
        //Your markup here
    @endif
@endif

Надеюсь, это поможет.

3 голосов
/ 09 июня 2019

Ну, я думаю, что проблема в вашей rola() функции в вашем User.php файле: вы определяете внешний ключ для отношения belongsTo, которое здесь равно id.

Это должно быть role_id, поскольку это ключ, который Eloquent будет пытаться сопоставить с id модели ролей. См. Документацию для получения дополнительной информации

0 голосов
/ 09 июня 2019

Проблема в вашей функции rola(). Вы используете неправильный внешний ключ с belongsTo. Это должно быть role_id, а не id (каковым оно является в настоящее время).

Вот фрагмент кода с некоторыми улучшениями:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
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',"avatar"
    ];
     /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
    * The attributes that should be cast to native types.
    *
    * @var array
    */

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function rola(){
        return $this->belongsTo("App\Roles", "role_id");
        //Or just return $this->belongsTo(Roles::class);
    }

    public function posts(){
        return $this->hasMany("App\Post");
    }

    public function comments(){
        return $this->hasMany("App\Comment");
    }

    public function isAdmin()
    {//dd($user);
        return $this->hasRole('admin');
    }

    public function isModerator()
    {//dd($user);
       return $this->hasRole('moderator');
    }

    public function isUser()
    {//dd($user);
        return 
        return $this->hasRole('user');
    }

    public function isPeon()
    {//dd($user);
        return $this->hasRole('peon');
    }

    public function hasRole($role)
    {
        return $this->rola->role === $role;
    }
}

Я предлагаю переименовать вашу функцию rola в модели ролей на users, поскольку она возвращает всех пользователей, у которых есть роль.

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Roles extends Model
{
    public function users(){
        return $this->hasMany(User::class, 'role_id');
    }
}

Еще одна вещь: взгляните на этот пакет . Это действительно помогает вам работать с пользователями, разрешениями и группами разрешений.

Надеюсь, это поможет.

...