Метод create
Метод create в классе Policy определяет, может ли текущий пользователь создавать новые экземпляры модели. Метод принимает текущего пользователя в качестве аргумента и возвращает булево значение - true если создание разрешено, и false если запрещено. В отличие от других методов политик, метод create не принимает конкретную модель, так как она ещё не создана.
Синтаксис
<?php
namespace App\Policies;
use App\Models\User;
use App\Models\Article;
class ArticlePolicy
{
public function create(User $user): bool
{
// логика проверки прав
}
}
?>
Определение политики
Создадим класс политики для модели Article с методом create. В данном примере разрешим создание только авторизованным пользователям:
<?php
namespace App\Policies;
use App\Models\User;
use App\Models\Article;
class ArticlePolicy
{
public function create(User $user): bool
{
return $user->id !== null;
}
}
?>
Теперь зарегистрируем политику в сервис-провайдере:
<?php
namespace App\Providers;
use App\Models\Article;
use App\Policies\ArticlePolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Article::class => ArticlePolicy::class,
];
public function boot(): void
{
$this->registerPolicies();
}
}
?>
Проверка права на создание
Проверим право на создание статьи для текущего пользователя через фасад Gate:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Support\Facades\Gate;
class ArticleController extends Controller
{
public function create()
{
if (Gate::allows('create', Article::class)) {
echo "User can create articles";
} else {
echo "User cannot create articles";
}
}
}
?>
Результат выполнения кода для авторизованного пользователя:
"User can create articles"
Использование метода authorize в контроллере для автоматического выброса исключения при отсутствии прав:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class ArticleController extends Controller
{
public function store(Request $request)
{
Gate::authorize('create', Article::class);
$article = Article::create([
'title' => $request->title,
'content' => $request->content,
'user_id' => auth()->id(),
]);
echo "Article created successfully";
}
}
?>
Сложная логика проверки
Реализуем политику, которая разрешает создание только пользователям с подтверждённым email и определённой ролью:
<?php
namespace App\Policies;
use App\Models\User;
use App\Models\Article;
class ArticlePolicy
{
public function create(User $user): bool
{
return $user->hasVerifiedEmail() && $user->role === 'editor';
}
}
?>
Использование в контроллере с обработкой ошибки:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Auth\Access\AuthorizationException;
class ArticleController extends Controller
{
public function store(Request $request)
{
try {
Gate::authorize('create', Article::class);
$article = Article::create([
'title' => $request->title,
'content' => $request->content,
'user_id' => auth()->id(),
]);
echo "Article created successfully";
} catch (AuthorizationException $e) {
echo "You are not allowed to create articles";
}
}
}
?>
Результат выполнения кода при недостатке прав:
"You are not allowed to create articles"
Использование в шаблонах Blade
Метод create также можно использовать непосредственно в шаблонах Blade для условного отображения элементов интерфейса:
@can('create', App\Models\Article::class)
<a href="{{ route('articles.create') }}">Create New Article</a>
@endcan
@cannot('create', App\Models\Article::class)
<p>You don't have permission to create articles</p>
@endcannot