实现用户权限管理
打赏作者

JellyBool

是一个系列,四个视频,后期还会更新 @codekissyoung

https://laravist.com/series/laravel-acl-in-action

arben

能否把laravel-acl demo code发我一份

charlie

怎么实现自己的文章只能自己编辑呢?怎么才能在middleware中获取到post过来的文章的作者id?

alias


求讲解,没看懂

alias
public function boot(GateContract $gate)
{
    $this->registerPolicies($gate);
    foreach($this->getPermission() as $permission){
    $gate->define($permission->name,function($user) use ($permission){
        return   $user->hasRole($permission->roles);
        });
    }
}

求讲解上述代码段…
getPermission函数是什么时候定义的?
闭包函数里function($user)调用的permission函数空间是在哪定义的…

这么一大段代码完全没讲解啊…

JellyBool

getPermissions()这个方法后面之间就定义了的啊。然后function($user)中的user就是一个参数,在回调函数中使用外部变量,可以使用`use (permission)来实现,这里的$permission`就是foreach当中的permission啊 @alias

chenze007 回复 JellyBool

原来如此 use ($permission) 之前还以为 是命名空间啥的 发现对不上号
原来是这样 “回调函数中使用外部变量”

JellyBool 回复 chenze007

恩,是的,这是 php 中比较奇葩的一点

237552032

@JellyBool
页面

@can('Article_Edit',$val)
@endcan

AuthServiceProvider.php

foreach($this->getPermissions() as $permissions){
            $gate->define($permissions->name,function($user,$article) use ($permissions){
                return $user->hasRole($permissions->roles) && $user->owns($article);
            });
        }

这样接受不到值是怎么回事

JellyBool

你在数据库中有定义 Article_Edit这个权限么?还有就是接受不到值是什么意思。。视频应该都有讲到的啊 @237552032

237552032

@JellyBool 数据库里有
页面

@can('Article_Edit')
@endcan

AuthServiceProvider.php

foreach($this->getPermissions() as $permissions){
            $gate->define($permissions->name,function($user) use ($permissions){
                return $user->hasRole($permissions->roles) && $user->owns($article);
            });
        }

这样写是对的

下面这种写法就不对了

@can('Article_Edit',$val)
@endcan

AuthServiceProvider.php

foreach($this->getPermissions() as $permissions){
            $gate->define($permissions->name,function($user,$article) use ($permissions){
               //这里是没执行到,也就是上面这个define()没有执行
                return $user->hasRole($permissions->roles) && $user->owns($article);
            });
        }
JellyBool

看一下PostPolicy这个,然后view使用

@can('update',$post)

@237552032

237552032

@JellyBool 不知道你说什么
换种方式:我就是想实行当前用户由编辑权限且文章是这个用户创建的才给编辑

@can('Article_Edit')
@can('articleShowPolicy',$val)

//要执行的语句

@endcan
@endcan
237552032

@JellyBool
这样写是报错的,哪里有介绍@can的用法啊!

JellyBool

哎。。你看看第二个视频 @237552032

237552032

@JellyBool 谢谢,解决了,主要对这个框架不熟,下面写法认为框架不支持的,写完页面报错,就认为是框架不支持了,原来是我写错个方法名。

@can('Article_Edit')
@can('articleShowPolicy',$val)

//要执行的语句

@endcan
@endcan

@can('Article_Edit') 会有返回值吗?

dylan
public function hasRole($role)
    {
        dd($this->roles);
        if(is_string($role)){
            return $this->roles->contains('name',$role);
        }
        return !! $role->intersect($this->roles)->count();
    }

$this->roles()roles带上括号会返回BelongsToMany对象,不带括号返回的是Collection,这是为什么?

JellyBool

当你使用$this->roles的时候,laravel会认为你想取得这个关联模型的collection,而如果你带上括号,也就是使用$this->roles(),laravel会明确知道你想返回BelongsToMany对象,这个时候以便于做更多地后续处理,比如使用$this->roles()->first() @dylan

dylan

@JellyBool 当我看到->role不带括号的时候,第一时间想到的是访问对象里面的属性,而不是方法,很明显User类里没有roles属性,只有roles()方法,这个地方$this->roles()$this->roles都可以使用,所以感觉怪怪的。

xshaitt

为什么突然在

foreach ($this->getPermissions() as $permission) {
            $gate->define($permission->name,function($user) use ($permission){
                return $user->hasRole($permission->roles);
            };
        }

这个 function ($user) 加了 user??视频 6分19秒

JellyBool 回复 xshaitt

是保证传入的参数是 User 的示例,这样减少出错的概率

xshaitt 回复 JellyBool

老师,我跟你的代码打的,laravel-v5.2.15. 有些地方不太一样.但是我有的改好了,就是一直没出先"编辑".视频9分43秒 修改好还是没出现

xshaitt 回复 JellyBool

laravel-v5.1.11

JellyBool 回复 xshaitt

你的表结构和字段都是跟视频一样的么?先试试在 hasRole 方法中直接返回 true 看看,这样就可以确定是不是这里的逻辑出问题了。

xshaitt 回复 JellyBool

老师, 我return true;之后还是没打印出来. 是因为哪里逻辑有问题吗?我打印出来

public function boot(GateContract $gate)
    {
        parent::registerPolicies($gate);
        foreach ($this->getPermissions() as $permission) {
        dd($permission->roles);
            $gate->define($permission->name,function(User $user) use ($permission){
                return $user->hasRole($permission->roles);
            });
        }
        
    }

发现是一个collection,然后程序到hasrole 该如何打印查看呢?hasrole几个intersect contains,还有一些$this->roles() 和 $role.比较的,学习感觉风中有点凌乱

JellyBool 回复 xshaitt

额。。。$this->roles() 是执行 roles 的方法,你对 oop 了解多少?hasRole 就是判断用户是否具有某个权限,思路是:传递进来的如果是一个 字符串,就判断这个字符串是否在 roles 的name集合当中,如果是 collection 就取交集,然后 count 一下

xshaitt 回复 JellyBool

额 可是我这里修改了 return true; 还是 没有出现’编辑’. 这个该如何排错呢. 在 boot里都可以打印出来.

public function hasRole($role)
    {
        
        //如果包含某一个 就说明有这个角色
        // if (is_string($role)) {
        //     return $this->roles->contains('name', $role);
        // }
        //  //如果是Collection
        // return !!$roles->intersect($this->roles->count());//是否相同 >0
        return true;
    }
xshaitt 回复 JellyBool

这是 打印的 dd($permission->roles);

Collection {#111#items: array:1 [▼
    0 => Role {#110#connection: null
      #table: null
      #primaryKey: "id"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:5 [▼
        "id" => 1
        "name" => "admin"
        "label" => "Admin"
        "created_at" => "2016-10-10 03:20:48"
        "updated_at" => "2016-10-10 03:20:48"
      ]
      #original: array:7 [▼
        "id" => 1
        "name" => "admin"
        "label" => "Admin"
        "created_at" => "2016-10-10 03:20:48"
        "updated_at" => "2016-10-10 03:20:48"
        "pivot_permission_id" => 1
        "pivot_role_id" => 1
      ]
      #relations: array:1 [▼
        "pivot" => Pivot {#109 ▶}
      ]
      #hidden: []
      #visible: []
      #appends: []
      #fillable: []
      #guarded: array:1 [▶]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
    }
  ]
}
xshaitt 回复 JellyBool

可以请您看下我的代码吗,是真的 跟您视频一起走的.
链接:http://pan.baidu.com/s/1i5Ji2HZ 密码:zcq9

xshaitt 回复 JellyBool

老师,ok了.根据这个 上面的来一遍, 搞定了. 是因为我数据库问题. 但是我还是想知道 在User中的hasRole(); 如何打印数据
http://9iphp.com/web/laravel/laravel-5-acl-define.html

JellyBool 回复 xshaitt

最简单的就是 \Log::info() 了吧。。

y7ut123 回复 xshaitt

你最后是哪里出了问题啊。。我也是出不来编辑按钮,按你的放法排查了,也没有解决

liudong0763

已看完,并做好了笔记

BuZhongSong

我使用的多表登录,怎么把权限跟我的admin表关联呢?查询语句报错是这样的:Base table or view not found: 1146 Table ‘cailanbao.clb_admin_role’ doesn’t exist (SQL: select clb_roles.*, clb_admin_role.admin_id as pivot_admin_id, clb_admin_role.role_id as pivot_role_id, clb_admin_role.created_at as pivot_created_at, clb_admin_role.updated_at as pivot_updated_at from clb_roles inner join clb_admin_role on clb_roles.id = clb_admin_role.role_id where clb_admin_role.admin_id = 1

JellyBool 回复 BuZhongSong

你照着 user_role 和 user_permission 等表创建 admin_role admin_permissoin 等表

YVEND

我在使用return $this->permissions()->save($permissions); 存储权限和角色时遇到laravel默认数据库名permissions_role 与我migration 创建的数据库permission_role不一致。多了一个s,数据库字段也是加了一个s 不知道怎么去指定数据库名和字段名呢。

JellyBool 回复 YVEND

声明关系的时候指定 关联表 :

public function permissions() {
     return $this->belongsToMany(Role::class,'permissions_role');
}
YVEND

我用的是5.3版本

YVEND

如果不申明关系,laravel会默认字段名是码表的 表名_id

xiaohj001

请问老师:关联表的表名的命名有规则吗?比如:permissions表和roles表的关联表名命名为permission_role或role_permission;users表和roles表的关联表名命名为user_role或role_user都可以吗?

JellyBool 回复 xiaohj001

其实这个表是可以自定义的,但是如果你使用 role_user 的时候, laravel 默认就是这个。如果你自定义表名的话,在声明关系的时候,直接:

return $this->belongsToMany(Path::class,'your_table_name')
laravelcasts 回复 xiaohj001

默认情况下,会按照类名首字母排序来找,也就是role_user,permission_role,他会按照类名去找,并且在model中声明$table也没用

Kwong Yan Chan
public function boot(GateContract $gate)
    {
        $this->registerPolicies($gate);
        foreach( $this->getPermissions() as $permission ){
            dump( $permission );
            $gate->define( $permission->name,function( User $user ) use ($permission){
                dump( '222' );
                return $user->hasRole( $permission->roles() ) ;#找到用户有多少规则
            } );
        }


    }

我的版本是5.1.45
第一个dump是打印出来了 ,第二个dump(‘222’) 完全没打印, 就是完全没进去? 闭包use适合5.1版本?

JellyBool 回复 Kwong Yan Chan

闭包是 php 的事情,跟 laravel 5.1 应该没有什么直接关系。

return $user->hasRole($permission->roles);
Kwong Yan Chan 回复 JellyBool

刚才tinker插入数据时候提示约束限制 插入不了。我再翻看一次视频吧。 搞了两小时不出来 。 返回的都是0,权限没有交集, 但数据库是OK 的啊 。。。

Kwong Yan Chan 回复 JellyBool

return出来的是0,!!后就是false ,权限是视频中所说的流程,但最后依然没见到编辑。 现在回滚。 数据库提示错误。处理中。。。。

Kwong Yan Chan

well.终于过了 ,哎呀心累。

insertSweat

我遇到一个非常奇怪的事情 下面这句放回的结果是1 不知道为什么

dd($role->intersect(null)->count());

我用laravel5.3 不知道是不是这个原因
但是下面这段 却是正常的返回0

$c = collect([1,2,3]);
dd($c->intersect(null)->count());
JellyBool 回复 insertSweat

第一个 $role 是不是查出来就是 空的 Colletion ?

insertSweat 回复 JellyBool

不是空的 有一个值
image

JellyBool 回复 insertSweat

具体是什么?贴出来看看?

insertSweat 回复 JellyBool

我无意中测试发现的有点不解,我代码和你视频中的一致如下

public function hasRole($role)
    {
        if(is_string($role)){
            return $this->roles()->contains('name', $role);
        }
        return !! $role->intersect($this->roles)->count();
    }

这个没问题 但是如果把最后一句return 的 改成如下

dd($role->intersect(null)->count());

返回的是1 我不理解在这里为什么回返回1

JellyBool 回复 insertSweat

这个就很奇怪了,我这测试的返回是 0 :

$collection = collect(['admin']);

dd($collection->intersect(null)->count());
insertSweat 回复 JellyBool

不是啊 我上面有说过啊 直接创建一个 collect对象的话确实是返回0

但是如过从用数据库查询之后的得到的collect对象的话就会返回集合的长度

JellyBool 回复 insertSweat

那具体数据库出来的是什么东西?哪种类型的对象?

insertSweat 回复 JellyBool

我上面贴了图片的啊

JellyBool 回复 insertSweat

那这很尴尬啊,我貌似还看不出来是什么引起的

insertSweat 回复 JellyBool

你那边测试过没有

JellyBool 回复 insertSweat

好像没啥问题

insertSweat 回复 JellyBool

算了 先不管了,也不影响使用

你可以这样 生成30条user测试数据 用下面这个路由 绝对放回的是 30

Route::get('/', function(){
    $users = \App\User::get();
    dd($users->intersect(null)->count());
});
JellyBool 回复 insertSweat

我猜可能是这两个原因:

1.null 特殊对待了
2.user中包含 空 的属性

zhangbao1992 回复 insertSweat

你代码的这部分写错了

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

应该是

return $this->roles->contains('name', $role);
萧十五郎

$this->roles() 与 $this->roles 有什么不同,什么情况下使用呢?

JellyBool 回复 萧十五郎

this->roles() 返回 QueryBuilder ,this->roles 返回一个 Collection

asion

@JellyBool 我照着写的代码,提示这样的错误,怎么解决,是什么问题呢?我的是laravel5.3
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation (View: D:\xampp\htdocs\lel_acl\resources\views\posts\show.blade.php)
in Model.php line 2709
at CompilerEngine->handleViewException(object(LogicException), ‘1’) in PhpEngine.php line 44
at PhpEngine->evaluatePath(‘D:\xampp\htdocs\lel_acl\storage\framework\views/aa12ebc811325182351306a629b880dc19966173.php’, array(’__env’ => object(Factory), ‘app’ => object(Application), ‘errors’ => object(ViewErrorBag), ‘post’ => object(Post))) in CompilerEngine.php line 59
at CompilerEngine->get(‘D:\xampp\htdocs\lel_acl\resources\views/posts/show.blade.php’, array(’__env’ => object(Factory), ‘app’ => object(Application), ‘errors’ => object(ViewErrorBag), ‘post’ => object(Post))) in View.php line 149
at View->getContents() in View.php line 120
at View->renderContents() in View.php line 85
at View->render() in Response.php line 45
at Response->setContent(object(View)) in Response.php line 201
at Response->__construct(object(View)) in Router.php line 1028
at Router->prepareResponse(object(Request), object(View)) in Router.php line 654
at Router->Illuminate\Routing{closure}(object(Request)) in Pipeline.php line 53
at Pipeline->Illuminate\Routing{closure}(object(Request)) in SubstituteBindings.php line 41
at SubstituteBindings->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing{closure}(object(Request)) in VerifyCsrfToken.php line 65
at VerifyCsrfToken->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing{closure}(object(Request)) in ShareErrorsFromSession.php line 49
at ShareErrorsFromSession->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing{closure}(object(Request)) in StartSession.php line 64
at StartSession->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing{closure}(object(Request)) in EncryptCookies.php line 59
at EncryptCookies->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing{closure}(object(Request)) in Pipeline.php line 104
at Pipeline->then(object(Closure)) in Router.php line 655
at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 629
at Router->dispatchToRoute(object(Request)) in Router.php line 607
at Router->dispatch(object(Request)) in Kernel.php line 268
at Kernel->Illuminate\Foundation\Http{closure}(object(Request)) in Pipeline.php line 53
at Pipeline->Illuminate\Routing{closure}(object(Request)) in CheckForMaintenanceMode.php line 46
at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing{closure}(object(Request)) in Pipeline.php line 104
at Pipeline->then(object(Closure)) in Kernel.php line 150
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 117
at Kernel->handle(object(Request)) in index.php line 54

JellyBool 回复 asion

你确定你照着写了?代码贴出来看看?

估计就是哪里忘记了 return 吧

asion 回复 JellyBool

是有个地方忘记return,谢啦

djsxianglei 回复 JellyBool

料事如神,果然忘写return了

hmengpang

为什么这里要两次取反呢

public function hasRole($role)
    {
        if(is_string($role)){
            return $this->roles()->contains('name', $role);
        }
        return !! $role->intersect($this->roles)->count();
    }
JellyBool 回复 hmengpang

就是取 bool 值。。

xiguage

public function hasRole(role){ if(is_string(role))
{
return this>roles>contains(name,this->roles->contains('name',role);
}
return role>intersect(role->intersect(this->roles)->count();
}

这里的$this->role 是哪里来的?

JellyBool 回复 xiguage

roles 这个方法

xiguage 回复 JellyBool

谢谢回复~~~

kdh40702

站长,
请问有没有单独讲解这部分的视频或文章,这边关系好难懂…

JellyBool 回复 kdh40702

好像没有,这个都难理解的话,你先看基础吧

kdh40702 回复 JellyBool

感谢回覆

还好多要学QAO

JellyBool 回复 kdh40702

laravel 的基础教程你看了没有?

kdh40702 回复 JellyBool

「Laravel 5.1 视频基础教程」看完了

还是我再重看一次「 Eloquent Relationship」这单元

ChildHua

视频最后那里,给角色分配权限,应该是把psermission 传过来而不是把role传过来吧?

xiaoshen

不错~~,用了一个权限映射表来把user表和roles表联系在一起,在通过roles查到权限;
如果有一个组的概念呢?想window系统一样有组,或者公司有部门的话?=>是不是 users查部门 再查roles 最后查permission?
user_department表+department_roles表+roles_permission表,这样去关联么?

JellyBool 回复 xiaoshen

有组的话,我们暂且称之为 group(跟 linux 一样),首先用户是哪个 group 的,就是 user_group,用户是哪个角色 user_role ,角色有哪些权限 role_permission ,也可以直接给某个组特定的角色 group_role

尼好再见

laravel 的 Gate 默认是验证 users 表的 我现在需要换成admins 这张表去哪里修改啊

JellyBool 回复 尼好再见

你看看多表认证那个视频

尼好再见 回复 JellyBool

多表认证我已经做好了,但是我现在做权限的话只对users这张表生效,admins这张表就无效了!也就是我前台登陆是有权限的,后台没有,但是我现在想要后台有权限,前台不需要

尼好再见 回复 JellyBool

我把config 下面的 auth.php 中的

'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

改成

'defaults' => [
        'guard' => 'admin',  //admin 是我的后台认证
        'passwords' => 'users',
    ],

这样的话确实权限认证到后台去了,但是我只想改 认证到后台 需要哪里去改啊!这边把整个defaults 改了 前台的认证那边都要改 比较麻烦

JellyBool 回复 尼好再见

多加一个呗,获取 User 的时候是 Auth::guard(‘admin’)->user()

尼好再见 回复 JellyBool

Gate 不是自动获取用户信息的吗?这个改在哪里能具体点吗!

尼好再见 回复 JellyBool

这个我之前看过,那也就是我每次都要传入 这个 $user不是吗? 能不能默认就是 后台的?应该有地方改吧!

JellyBool 回复 尼好再见

应该有地方改吧 这个我没有试过。

但是实现了多表登录认证之后,登录进来的用户就可以使用 Gate 了吧,理论上对应的 role_admin permission_admin 等关联表做好就行

尼好再见 回复 JellyBool

jelly 什么时候有空录制一个系列可以在真实工作环境经常写的代码吧比如下面几点一般小公司都要做这些

  1. 前后台分离(之前录制过)

  2. 后台管理员的权限,最好是后台可以对功能进行配置权限的那种 后台结合自己的后台 admins 表

  3. 后台数据的增删改查,主要讲讲检索功能(配合vue)比如日期区间、或者某个类型、用户的等级类似这些东西

  4. 后台多图上传最好配合 vue

  5. 前台给手机端提供API接口(分用户登陆后访问的,无需用户登陆后即可访问)

  6. 前台的产品的分页(vue)类似淘宝的排序检索

  7. 搜索功能

  8. 接入各种登陆

  9. 接入各种支付

(以上这些 其实都是在你视频的各个系列里有讲,比较零散)

差不多很多工作中经常用的功能,这样一个系列应该会有很多人需要把!可能我列举的还不够完整,可以发个帖子工作中常常需要的功能,然后把所有需要的结合起来将一个系列
哈哈这只是我个人的需求和建议给你参考参考顺便解决我的烦恼

JellyBool 回复 尼好再见

OK的,我可以看看

尼好再见

版本 Laravel 5.4
我把users 表 换成 admins 表了 其他都没变
在Admin model 中 下面方法 的 $this->roles 报错了!

public function hasRole($role) {
        if(is_string($role)){
            return $this->roles->contains('name', $role);
        }
        
        return !! $role->intersect($this->roles)->count();
    }

这个是什么问题

Whoops, looks like something went wrong.
(2/2) QueryException
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'redis.admin_role' doesn't exist (SQL: select `roles`.*, `admin_role`.`admin_id` as `pivot_admin_id`, `admin_role`.`role_id` as `pivot_role_id` from `roles` inner join `admin_role` on `roles`.`id` = `admin_role`.`role_id` where `admin_role`.`admin_id` = 1)

为什么是 redis.admin_role 而不是 redis.role_admin

JellyBool 回复 尼好再见

这些关系你还是要照着 users 的关系来一遍啊 admin_role

尼好再见 回复 JellyBool

jelly 话说我要把权限给 vue 怎么操作啊!就是比如我有一个删除的权限,前台点击删除的时候是访问一个post 请求的 然后我 后台给权限判断 是可以禁止删除的,但是 我想最好 vue里面 列表出来的时候就直接把删除这个按钮去掉,blade 中有 @can 可以用 但是 vue 里面该怎么操作呢?给个思路吧 !谢谢

JellyBool 回复 尼好再见

后端判断好之后返回呗,或者你前端根据 user_id 做一次判断。当然后端的判断是不能少的

UncleCaozy

这里面的

$user->$roles->save($role)

其实和

$user->$roles->attach($role)

是一个意思吧,添加用attach,移除detach,现在有了toggle这个方法 ,对处理关系表的操作好像更方便了一点吧

JellyBool 回复 UncleCaozy

嗯,是的啊。之前录视频的时候没有 toggle 的

UncleCaozy 回复 JellyBool

现在天天在这里学习,希望今年能有个大的提升。。。。。。。

UncleCaozy

感觉GivePermission()这个方法会不会多此一举啊,直接permissions()->save($permission)或者permissions()->attach($permission)也行吧,感觉没差啊,多绕了一下,只不过没有give来的形象。。。(前面发现说错了,改了一下。。。。。)

JellyBool 回复 UncleCaozy

就是为了可读一点吧

乔泓恺-Jone

一直有个问题困扰我 麻烦帮忙给点意见 谢谢
问:一个用户没有修改全部文章中A文章的权限(也许会有其他文章BCD的修改权限),这样是看不到文章A是编辑按钮和进不去编辑页面的,这个很明显。可是问题是,在修改保存的时候是否有必要再一次确定用户是否有权限那?

JellyBool 回复 乔泓恺-Jone

我觉得做吧,比如在 update 的时候做一遍检查

乔泓恺-Jone 回复 JellyBool

好嘞! !!

Nixus
$user->roles()->save($role)

这个操作的前提是,在 role_user 表中已经做了外键关联,然后在执行这个操作的时候,laravel 会自动选取 $role 这个 collection 中的 id ,插入到 role_user 表中,如果没有做相应的外键关联,这样的操作就是不可行的
可以这么理解吗?

JellyBool 回复 Nixus

嗯,是要指定关联关系先

laravelcasts 回复 Nixus

应该是eloquent model 的关联关系要声明 ,也就是$this->belongsToMany(),mysql(migration) 的外键约束可以不用声明(如果你说的外键关联是这个的话)

djsxianglei

Psy Shell v0.8.15 (PHP 5.6.27 鈥?cli) by Justin Hileman

>>> namespace App;
>>> $role = new Role;
=> App\Role {#711}
>>> $role->name='admin';
=> "admin"
>>> $role->label='Admin';
=> "Admin"
>>> $role->save();
=> true
>>> $permission = new Permission;
=> App\Permission {#117}
>>> $permission->name='edit_form';
=> "edit_form"
>>> $permission->label='edit the form';
=> "edit the form"
>>> $permission->save();
=> true
>>> $role->givePermission($permission);
PHP Fatal error:  Call to a member function save() on null in F:\www\test.dev\app\Role.php on line 19


  [Symfony\Component\Debug\Exception\FatalErrorException]
  Call to a member function save() on null

我执行role>givePermission(role->givePermission(permission);报错误

 Call to a member function save() on null

老师是什么原因

JellyBool 回复 djsxianglei

大概是 givePermission 里面的 $role->save() 类似的代码中 ,role 是一个空值

djsxianglei 回复 JellyBool

那该怎么修改?我和您视频里面都一样,我用的是laravel5.4

JellyBool 回复 djsxianglei

目前的信息我不知道啊,你把相关代码贴出来看看?

inottn

想问一下,save() 和 attach() 这两个方法的区别是什么啊?

wwhu668 回复 inottn
    public function save(Model $model, array $pivotAttributes = [], $touch = true)
    {
        $model->save(['touch' => false]);

        $this->attach($model->getKey(), $pivotAttributes, $touch);

        return $model;
    }
inottn 回复 wwhu668

谢谢老哥,大概了解了,我还有个疑问,第三个参数 $touch 的作用是什么。

Flourishing

感觉Jelly 早期有点炫技 啊 真的看这个视频的 都是不会的 你讲这么快…