Хранение данных в виде массива или JSON в ноде

Главные вкладки

Аватар пользователя buddy90210 buddy90210 8 января 2021 в 9:30

Всех с праздниками!
Подскажите пути решения, как хранить массив в базе данных?
Задача:
Имеем сущность (ноду) в ней куча полей, автор ноды должен иметь возможность разным пользователям позволять редактировать разные поля.
Решение (как вижу я): У ноды есть поле в котором содержится массив данных примерно в таком виде:

<?php  Array (
            [
id1] => Array
                (
                    [
field1] => rule 1
                    
[field2] => rule 2
                    
.
                    .
                    .
                )

            [

id2] => Array
                (
                    [
field1] => rule 1
                    
[field2] => rule 2
                    
.
                    .
                    .
                )
  )
?>

Где id - это id пользователя.
Данный массив "собирается" автором ноды.
В функции (препроцесса например) я сравниваю значения и в зависимости от данных выдаю разрешения пользователям.

Вопрос: Как хранить данный массив в БД? Или лучше использовать JSON и хранить как файл?
Вариант с массивом удобней, так как вся логика исполняется PHP и ни каких преобразований делать необходимости нет.
В ядре есть модули сериализации и JSON, но как то никогда не имел с ними дел, подойдут ли они?
А может есть более "правильное" решение?

Лучший ответ

Аватар пользователя buddy90210 buddy90210 10 января 2021 в 10:14

Спасибо всем за наводки и подсказки! В очередной раз убедился в необходимости лишний раз пересмотреть задачу и пути решения с разных сторон!
Остановился на кастомной SQL таблице, пожалуй, это самый простой и гибкий путь.

Комментарии

Аватар пользователя ivnish ivnish 8 января 2021 в 9:36

buddy90210 wrote: иметь возможность разным пользователям позволять редактировать разные поля.

Что-то Вы усложняете, мне кажется. Если уж задача действительно такая, то я бы

  • Дал права общей роли на редактирование нод
  • Доступ к полям ограничивал бы по ролям с помощью модулей типа field_permissions

Зачем изобретать велосипеды и что-то самому писать в БД, когда уже всё давно изобрели?

Аватар пользователя buddy90210 buddy90210 8 января 2021 в 9:40

Изначально так и планировал (на основе ролей) делать. Но проблема в том что нет определенного набора разрешений на редактирование полей, т.е. одна и та же роль может редактировать разный набор полей или вообще не может просматривать ноду.

Аватар пользователя marassa marassa 8 января 2021 в 9:36

buddy90210 wrote: Имеем сущность (ноду) в ней куча полей, автор ноды должен иметь возможность разным пользователям позволять редактировать разные поля.

Навскидку это выглядит как ошибка проектирования. Можно прояснить о какой предметной сущности идёт речь, почему у нее так много атрибутов и почему их должны редактировать разные пользователи?

Аватар пользователя buddy90210 buddy90210 8 января 2021 в 9:49

Сущность типа "проект", у нее есть связанные ноды - работы, материалы и другие атрибуты.
Автор проекта может дать пользователю разрешение на редактирование любого из атрибутов или на просмотр его.
Простой пример:
Компания строит дом, сотрудник А может добавлять работы и редактировать их, а Сотрудник Б не может, но зато может Управлять материалами. А вот заказчик дома вообще ничего не может редактировать и добавлять, а только просматривать, при этом с другими ценами на работы и материалы.
В плане реализации, по моему мнению, это наиболее удобный вариант, при загрузке проекта сравниваем текущего пользователя с данными массива, если нашли загрузили и дали определенные разрешения (по сути какие угодно).

Аватар пользователя buddy90210 buddy90210 8 января 2021 в 10:01

Речь идет не столько о разрешениях на редактирование полей, сколько о возможности при загрузки ноды получить массив данных, исходя из которого определять логику дальнейшего поведения для текущего пользователя.
Пока, что мне пришло в голову это именно связанный с нодой массив данных.

Аватар пользователя marassa marassa 8 января 2021 в 10:19

buddy90210 wrote: Сущность типа "проект", у нее есть связанные ноды - работы, материалы и другие атрибуты

Связанные ноды это не атрибуты. Доступ к нодам реализуется проще, чем к индивидуальным полям.

buddy90210 wrote: Компания строит дом, сотрудник А может добавлять работы и редактировать их, а Сотрудник Б не может, но зато может Управлять материалами

Не имеет никакого отношения к доступу к полям.

buddy90210 wrote: Речь идет не столько о разрешениях на редактирование полей, сколько о возможности при загрузки ноды получить массив данных, исходя из которого определять логику дальнейшего поведения для текущего пользователя.

Такой массив данных вместе с API уже имеется в ядре Друпала, называется Permissions.

Аватар пользователя buddy90210 buddy90210 8 января 2021 в 10:38

marassa wrote: Такой массив данных вместе с API уже имеется в ядре Друпала, называется Permissions.

Да, знаком с ним. Сложность в том, что для реализации необходимого функционала надо как то "сказать" Друпалу что этому пользователю для этого проекта можно добавлять связанные ноды и даже можно редактировать добавленные не им, а вот для другого проекта можно добавлять связанные ноды но вот менять не свои нельзя. Т.е. функционал очень гибкий и не может зависеть от роли, так как проектов может быть много и в каждом он может иметь свои разрешения, более того иметь свои проекты в которых сам может раздавать разрешения.
Именно по этому решил, что необходимо привязаться к ноде проект так как все идет от нее.
И да, согласен, с полями это не очень удачный пример)

Аватар пользователя buddy90210 buddy90210 8 января 2021 в 10:48

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

<?php$json = json_encode($array);
//////
$decode = json_decode($json, true);?>

При загрузке ноды пробегаюсь по массиву, если есть id текущего пользователя, смотрю что ему можно (все в том же массиве) и действую по результату. А там уже как хочешь, хочешь форму не выводи хочешь permission'ом запрещай.
Что скажете?

Аватар пользователя ivnish ivnish 8 января 2021 в 11:01

У marassa, кстати, неплохой опыт проектирования систем. Рекомендую последовать его советам и перестать изобретать велосипеды

Аватар пользователя marassa marassa 8 января 2021 в 14:49

Да я не настаиваю ни на чём, и опыта проектирования подобных систем с таким распределением прав доступа у меня нет, просто я бы хотя бы попробовал пойти по пути использования и, если необходимо, расширения штатных механизмов, чем нахлобучивать сбоку от Друпала свой собственный механизм для управления правами. Это скорее какой-то джумла-вэй чем друпал-вэй Wink Хотя работать будет скорее всего - почему нет?

Аватар пользователя ivnish ivnish 8 января 2021 в 15:08

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

Аватар пользователя marassa marassa 9 января 2021 в 8:39

Могу сформулировать, что конкретно мне не нравится в предлагаемом подходе. Если хранить права доступа к фрагментам проекта в виде сложносочиненного текстового поля в самом проекте, то единственным мало-мальски удобным юз-кейсом/разрезом будет просмотр и проверка прав для конкретного проекта. А что если Вам захочется (а ведь захочется) посмотреть к каким проектам допущен Сотрудник А? Или посмотреть какие сотрудники имеют право Управлять материалами для разных проектов? Это ж надо вместо простого индексированного запроса к БД грузить последовательно в память все проекты (а если их тыщи?), разбирать это текстовое поле и принимать решение включать данную запись в выборку или нет. Мало того, что это будет очень медленно, это же целая куча кастомного кода, который надо как-то интегрировать с views и т.п.

Аватар пользователя buddy90210 buddy90210 9 января 2021 в 10:08

marassa wrote: Вам захочется (а ведь захочется) посмотреть к каким проектам допущен Сотрудник А? Или посмотреть какие сотрудники имеют право Управлять материалами для разных проектов? Это ж надо вместо простого индексированного запроса к БД грузить последовательно в память все проекты (а если их тыщи?)

А вот с этим полностью согласен! Неправильно как то. Надо подумать над более правильной реализацией!
В принципе, добавка дополнительного поля типа Entity Reference с сылкой на пользователя должна решить данную задачу?

Аватар пользователя marassa marassa 9 января 2021 в 10:10

А более правильной реализацией хранения сложных структур данных является:
1) Использование СУБД с ее полями, индексами и SQL;
2) По возможности использование уже имеющихся структур и механизмов CMS, тем более что Drupal позволяет при необходимости очень гибко и элегантно их расширять, не ломая и не переписывая заново.

Аватар пользователя buddy90210 buddy90210 9 января 2021 в 11:45

marassa wrote: 2) По возможности использование уже имеющихся структур и механизмов CMS, тем более что Drupal позволяет при необходимости очень гибко и элегантно их расширять, не ломая и не переписывая заново.

Не вижу очевидных решений, как реализовать данный функционал путем друпала.

marassa wrote: 1) Использование СУБД с ее полями, индексами и SQL;

Склоняюсь к кастомной таблице в которой и буду хранить все данные по проектам пользователям и их разрешениям, наверное это самый правильный путь.

Аватар пользователя gun_dose gun_dose 9 января 2021 в 14:44

Можно просто засунуть все поля в параграфы. А в параграфе сделать поле с референсом на юзера, типа кому можно редактировать. Можно сделать даже несколько полей, типа кому можно, кому нельзя, кому можно только по пятницам и т.д.

Ну и там уже в хуках высчитывать доступ к полю через этот референс.

Аватар пользователя buddy90210 buddy90210 10 января 2021 в 10:14

Спасибо всем за наводки и подсказки! В очередной раз убедился в необходимости лишний раз пересмотреть задачу и пути решения с разных сторон!
Остановился на кастомной SQL таблице, пожалуй, это самый простой и гибкий путь.