laravel 如何在laravel 5中建立用户和角色关系?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32297939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:16:40  来源:igfitidea点击:

How to make user, and roles relationship in laravel 5?

laravellaravel-5eloquent

提问by Gautam Kumar

I have two tables :

我有两张桌子:

User ->
 id : 
 name : 
 role_id : ->refernces('id')->on('roles');

Roles ->
 id :
 role_name :
 access :

I am trying to access roles details from user.

我正在尝试从用户访问角色详细信息。

My user model has :

我的用户模型有:

public function role(){
        return $this->belongsTo('App\Role');
    }

My role model has :

我的榜样有:

public function user(){
      return $this->hasMany('App\User');
  }

When I try to do following :

当我尝试执行以下操作时:

$user = User::find(1);

        $details = [
            'name' => $user->first_name,
            'role' => $user->role->role_name

        ];

I get error :

我得到错误:

Trying to get property of non-object

My roles table contains access columns containing array of permissions to different routes. So my user will have only one role. While a role can have multiple users. How to do that?

我的角色表包含​​访问列,其中包含对不同路由的权限数组。所以我的用户将只有一个角色。而一个角色可以有多个用户。怎么做?

采纳答案by Gautam Kumar

I got the problem, i was having a role column in user table, so when i was doing

我遇到了问题,我在用户表中有一个角色列,所以当我在做

$user->role->role_name

it was fetching rolecolumn instead of relationship.

它正在获取role列而不是关系。

回答by Safoor Safdar

In my recent project, I handled these requirement in that way.. First of All Database Table Structure/Migration

在我最近的项目中,我以这种方式处理了这些需求.. 首先是数据库表结构/迁移

User Table

用户表

class CreateUserTable extends Migration {

    public function up() {
        Schema::create('user', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->boolean('status')->default(0);
            $table->boolean('is_admin')->default(0);
            $table->boolean('notify')->default(0);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    public function down() {
        Schema::drop('user');
    }

}

Role Table

角色表

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateRoleTable extends Migration {
    public function up()
    {
        Schema::create('role', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name')->unique();
            $table->string('display_name')->nullable();
            $table->string('description')->nullable();
            $table->boolean('status')->default(0);
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::drop('role');
    }

}

Role And User Relation Table

角色和用户关系表

class CreateRoleUserTable extends Migration {
    public function up() {
        // Create table for associating roles to users (Many-to-Many)
        Schema::create('role_user', function (Blueprint $table) {
            $table->integer('user_id')->unsigned();
            $table->integer('role_id')->unsigned();

            $table->foreign('user_id')->references('id')->on('user')
                ->onUpdate('cascade')->onDelete('cascade');
            $table->foreign('role_id')->references('id')->on('role')
                ->onUpdate('cascade')->onDelete('cascade');

            $table->primary(['user_id', 'role_id']);
        });
    }

    public function down() {
        Schema::drop('role_user');
    }

}

After these table you have to handle permission by assigning to specific Role.

在这些表之后,您必须通过分配给特定角色来处理权限。

Permission

允许

class Permission extends Migration {

    public function up() {
        Schema::create('permission', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name')->unique();
            $table->string('pattern');
            $table->string('target');
            $table->string('module');
            $table->string('display_name')->nullable();
            $table->boolean('status')->default(0);
            $table->timestamps();
        });
    }

    public function down() {
        Schema::drop('permission');
    }

}

Permission and Role Table Relation

权限和角色表关系

class PermissionRole extends Migration {
    public function up() {
        // Create table for associating roles to permission (Many-to-Many)
        Schema::create('permission_role', function (Blueprint $table) {
            $table->integer('permission_id')->unsigned();
            $table->integer('role_id')->unsigned();

            $table->foreign('permission_id')->references('id')->on('permission')
                ->onUpdate('cascade')->onDelete('cascade');
            $table->foreign('role_id')->references('id')->on('role')
                ->onUpdate('cascade')->onDelete('cascade');

            $table->primary(['permission_id', 'role_id']);
        });
    }

    public function down() {
        Schema::drop('permission_role');
    }

}

And Finally our model would look alike:

最后我们的模型看起来很像:

User Model

用户模型

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {

    use Authenticatable, CanResetPassword;
    protected $table = 'user';
    protected $fillable = ['name', 'email', 'password', 'is_admin'];
    protected $hidden = ['password', 'remember_token'];

    public function scopeActive($query) {
        return $query->whereStatus('1');
    }
    public function scopeAdmin($query) {
        return $query->whereIsAdmin('1');
    }
    public function scopeNotify($query) {
        return $query->whereNotify('1');
    }

    public function roles() {
        return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
    }

    public function attachRole($role) {
        if (is_object($role)) {
            $role = $role->getKey();
        }
        if (is_array($role)) {
            $role = $role['id'];
        }
        $this->roles()->attach($role);
    }

    public function detachRole($role) {
        if (is_object($role)) {
            $role = $role->getKey();
        }
        if (is_array($role)) {
            $role = $role['id'];
        }
        $this->roles()->detach($role);
    }

    public function attachRoles($roles) {
        foreach ($roles as $role) {
            $this->attachRole($role);
        }
    }

    public function detachRoles($roles) {
        foreach ($roles as $role) {
            $this->detachRole($role);
        }
    }

    public function isSuperUser() {
        return (bool)$this->is_admin;
    }

    public function hasAccess($permissions, $all = true) {
        if ($this->isSuperUser()) {
            return true;
        }
        return $this->hasPermission($permissions, $all);
    }

    public function hasPermission($permissions) {
        $mergedPermissions = $this->getMergedPermissions();
        //dd($mergedPermissions);
        if (!is_array($permissions)) {
            $permissions = (array)$permissions;
        }

        foreach ($permissions as $permission) {
            $matched = false;
            // We will set a flag now for whether this permission was
            // matched at all.
            $founded_perms = find_in($mergedPermissions, "name", $permission);
            if (!empty($founded_perms)) {
                $matched = true;
            }

        }

        if ($matched === false) {
            return false;
        }

        return true;
    }

    public function getMergedPermissions() {
        $permissions = array();
        foreach ($this->getRoles() as $group) {
            $permissions = array_merge($permissions, $group->permissions()->get()->toArray());
        }
        return $permissions;
    }

    public function getRoles() {
        $roles = [];
        if ($this->roles()) {
            $roles = $this->roles()->get();
        }
        return $roles;
    }
}

Role Model

好榜样

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model {
    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'role';
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'display_name', 'description'];

    public function scopeActive($query) {
        return $query->whereStatus('1');
    }

    /**
     * Many-to-Many relations with User.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function users() {
        return $this->belongsToMany('App\User');
    }

    public function permissions() {
        return $this->belongsToMany("App\Permission");
    }

}

Permission Model

权限模型

namespace App;

use Illuminate\Database\Eloquent\Model;

class Permission extends Model {
    protected $table = 'permission';
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'pattern', 'target', 'module', 'display_name', 'status'];

    public static function displayable() {
        $prepared_array = [];
        $temp = self::orderBy('module')->get()->toArray();
        foreach ($temp as $sin) {
            $prepared_array[$sin['module']][] = $sin;
        }
        return $prepared_array;
    }
    public function scopeActive($query) {
        return $query->whereStatus('1');
    }

    public function roles() {
        return $this->belongsToMany("App\Role");
    }
}

Well, thats the basic structure helped to implement basic ACL and Auth with laravel 5.

好吧,这就是帮助使用 laravel 5 实现基本 ACL 和 Auth 的基本结构。

Let me know if you have any further related question. Or If you need complete implementation I'll provide it to you.

如果您有任何进一步的相关问题,请告诉我。或者,如果您需要完整的实施,我将提供给您。

回答by Bogdan

For a one-to-manyrelationship you don't need a pivot table, so you can delete the user_rolestable. Then add a role_idcolumn to your userstable, that will reference the idcolumn in for your rolestable. Next define the relations as follows for each of your models:

对于一对多关系,您不需要数据透视表,因此您可以删除该user_roles表。然后role_id向您的users表中添加一列,该id列将引用您的roles表中的列。接下来为每个模型定义如下关系:

// User.php
public function role()
{
    return $this->belongsTo('App\Role');
}

and

// Role.php
public function users()
{
    return $this->hasMany('App\User');
}

Now you can access your role via the relation like this:

现在您可以通过这样的关系访问您的角色:

$user->role->name;

回答by Frederiek

i noticed you are not using the laravel default table naming conventions, you are using user_roles whereass laravel naming conventions state you should use: role_user (alphabetical and singular)

我注意到您没有使用 Laravel 默认表命名约定,您使用的是 user_roles 而 Laravel 命名约定声明您应该使用:role_user(字母和单数)

you could override the belongsToMany by stating your custom table name ofcource.

您可以通过声明您的自定义表名 ofcource 来覆盖belongsToMany。

public function users() {
    return $this->belongsToMany('App\User', 'user_roles');
}

on the second node there are also some good libraries to handle these kind of things, take a look at : https://github.com/romanbican/roles

在第二个节点上也有一些很好的库来处理这些事情,看看:https: //github.com/romanbican/roles