Рекурсивные отношения Laravel

#php #mysql #laravel #eloquent

#php #mysql #laravel #красноречивый

Вопрос:

У меня есть следующие таблицы:

 directories
    id
    parent_directory_id

users
    id

user_directory_access
    directory_id
    user_id
  

Пример:

Мне нужно найти directories с помощью id of 45 , который имеет любой рекурсивный parent_directory_id, который присутствует в user_directory_access таблице, которая имеет user_id of 3

В идеале я бы хотел, чтобы пользователь автоматически наследовал доступ к каталогу, если у него есть доступ к любому из родительских каталогов (рекурсивный по всей иерархии), так что, например, если у меня есть доступ к корневому каталогу, мне должен быть разрешен доступ ко всем дочерним элементам через 1 запись, хранящуюся в user_directory_access таблице.

Что было бы жизнеспособным решением? Я открыт для реструктуризации, если потребуется.

Комментарии:

1. Существует ли фиксированный предел глубины вложенности каталогов?

2. Нет, никаких ограничений не накладывается

Ответ №1:

У вас может быть карта (кэшированная в memcache, файле или в другой таблице) directory_id и список parent_directory_id его родителей, поэтому для этой структуры:

 1
┣━━━2
┃   ┗━━━4
┃       ┗━━━5
┗━━━3
  

Ваша карта будет выглядеть следующим образом:

 $parents_map = [
    1 => [],
    2 => [1],
    3 => [1],
    4 => [2, 1],
    5 => [4, 2, 1],
];
  

Всякий раз, когда вы добавляете новый дочерний каталог, найдите parents_map его собственного родителя и добавьте его на карту:

 // new directory 6 whose parent is 3:
$new_id = 6;
$parent_id = 3;
$parents_map[$new_id] = array_merge([$parent_id], $parents_map[$parent_id]);
  

Затем, когда вам нужно проверить разрешения для каталога, найдите его на карте и посмотрите, есть ли у кого-либо из его родителей разрешение.

 $directory_id = 6;
foreach($parents_map[$directory_id] as $parent_id) {
    check_permissions($user_id, $parent_id);
}