Я у себя применял подход, взятый у
гема CanCan из RubyOnRails.
Идея такова: определяем trait Ability и добавляем ему к классу User. Сам этот trait имеет метод can, который разрешает/запрещает определенное действие:
<?php
trait Ability
{
public function can($verb, $noun)
{
$class = is_string($noun) ? $noun : get_class($noun);
if(is_callable([this, "canManage$class"]))
{
$this->{"canManage$class"}($verb, $noun);
} else {
$this->fallback($verb, $noun);
}
}
public function canManageUser($verb, $noun)
{
switch($verb) {
case 'create':
return true;
case 'edit':
if ($this->isAdmin()) return true;
if ($noun->id == $this->id) return true;
break;
case 'delete':
case 'destroy':
if ($noun->id == $this->id) return false;
break;
}
return $this->fallback($verb, $noun);
}
public function fallback($verb, $noun)
{
if ($this->isAdmin()) return true;
return false;
}
public function isAdmin()
{
return $this->role == self::ADMIN;
}
}
Таким образом мы изолируем семантику ролей в одном конкретном месте, и определяем разрешения не на уровне класса Сущностей, а на уровне конкретной сущности, что гораздо гибче.
Что касается использования в view, то никаких проблем:
@if(Auth::user() && Auth::user()->can('edit', $page))
<form></form>
@endif
@if(Auth::user() && Auth::user()->can('create', 'Page'))
<a href="#">Добавить страницу</a>
@endif