Я предлагаю вам использовать политики для моделей Todo и TodoList, а также область действия, чтобы ограничить задачи одним пользователем для предотвращения дублирования кода в вашем приложении:
class ToDoListPolicy
{
public function view(User $user, TodoList $post)
{
return $user->id === $todolist->user_id;
}
}
class ToDoPolicy
{
public function edit(User $user, Todo $toDo)
{
$toDo->loadMissing('todolist');
return $user->id === $toDo->todolist->user_id;
}
}
Зарегистрируйте их в ваш AuthServiceProvider. php
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
TodoList::class => ToDoListPolicy::class,
Todo::class => ToDoPolicy::class
];
}
и затем используйте их в своих действиях:
public function getTodosForTodolist(Todolist $toDoList)
{
$this->authorize('view', $toDoList);
$toDoList->loadMissing('todos');
return view('todo.index', ['todos' => $toDoList->todos);
}
class ToDoController extends Controller
{
public function edit(Todo $toDo)
{
$this->authorize('edit', $toDo);
return view('todo.edit', compact('toDo'));
}
}
И область действия, чтобы ограничить запрос указанным c user:
class Todo extends Model {
// ...
public function scopeByUser(Builder $query, ?User $user = null)
{
if (! $user) {
$user = Auth::user();
}
$query->whereHas('todolist', function (Builder $toDoListQuery) use ($user) {
$toDoListQuery->where('user_id', $user->id);
});
}
}
Ответ на ваши вопросы в комментариях.
Q1: Я должен был поставить Auth::user()->can('view', $todolist);
в if Еще одна оговорка, чтобы это работало. Угадайте, как это работает?
Q2: в чем разница между $this->authorize('edit', $todo)
и Auth::user()->can('edit', $todo)
?
Извините, это была ошибка на моей стороне. Auth::user()->can()
возвращает логическое значение, тогда как $this->authorize()
(который является методом черты AuthorizesRequests, обычно включаемой в BaseController) выдает исключение , если авторизация не удалась .