Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Сформировать один массив роль\права из 3х (https://javascript.ru/forum/dom-window/79936-sformirovat-odin-massiv-rol%5Cprava-iz-3kh.html)

jabbascript 09.04.2020 07:38

Сформировать один массив роль\права из 3х
 
Здравствуйте!!!
Подскажите как можно сформировать из данных массивов полученных с апи:
const roleRight = [
		{
			"Id": 1,
			"RoleId": 1,
			"RightId": 1
		},
		{
			"Id": 2,
			"RoleId": 1,
			"RightId": 2
		},
		{
			"Id": 3,
			"RoleId": 2,
			"RightId": 2
		},
		{
			"Id": 4,
			"RoleId": 3,
			"RightId": 1
		},
	];

	const roles = [
		{
			"Id": 1,
			"Name": "Администратор",
		},
		{
			"Id": 2,
			"Name": "Модератор",
		},
		{
			"Id": 3,
			"Name": "Пользователь",
		},
	];

	const rights = [
		{
			"Id": 1,
			"Name": "Контакты - Просмотр",
		},
		{
			"Id": 2,
			"Name": "Контакты - Редактирование",
		}
	];

Пимерно такой т е основываясь на roleRights сформировать массив обьестов где содержится Роль и ее права.
const roles = [
		{
			"Id": 1,
			"Name": "Администратор",
			"right": [
				{
					"Id": 1,
					"Name": "Контакты - Просмотр",
				},
				{
					"Id": 2,
					"Name": "Контакты - Редактирование",
				}
			]
		},
		{
			"Id": 2,
			"Name": "Модератор",
			"right": [
				{
					"Id": 1,
					"Name": "Контакты - Просмотр",
				},
				{
					"Id": 2,
					"Name": "Контакты - Редактирование",
				}
			]
		},
	];

рони 09.04.2020 08:17

jabbascript,
непонятно как формируется массив прав ...

laimas 09.04.2020 08:56

рони,
наверное так - roles[i][RoleId], соответственно и права по RightId

рони 09.04.2020 09:03

Цитата:

Сообщение от laimas
права по RightId

не вижу массива RoleId

laimas 09.04.2020 09:24

рони,
roles[index][Id] == roleRight[index][RoleId] = "Администратор", ...
Соответственно и права но уже по равенству RightId и Id из rights. Видимо так.

Как только проверять такие права, не представляю.

рони 09.04.2020 09:41

laimas,
:-? нет массива индексов прав, нет массива правил
либо здесь "RightId": 1 массив
либо тут немассив "right": []

laimas 09.04.2020 09:51

Вообще, нужно не const roles модифицировать (да и не получится), а обходить первичный объект, а это const roleRight, вот это более всего отвечает первичной таблице в базе - юзеры. А roles и rights, это связанные таблицы описывающие роли и их права.

И все будет связываться, иначе нет логики.

laimas 09.04.2020 10:15

рони, надо конечно автора заставить высказаться, но по идее так должно быть:

Код:

users
-------------------------------
id | name  | role | right
-------------------------------
1  | Duke  | 1    | 1
2  | Sam  | 1    | 2
3  | John  | 2    | 2
4  | Peter | 3    | 1

roles
-------------------------------
id | name
-------------------------------
1  | Администратор
2  | Модератор
3  | Пользователь

rights
-------------------------------
id | name
-------------------------------
1  | Контакты - Просмотр
2  | Контакты - Редактирование

Вот так они и связаны. Если же все помещать в roles, то это равноценно запросу в базе, по которому нужно получить всех юзеров с определенными ролями, заодно и их права, в котором первичной таблицей выбрана таблица ролей. Если при этом то что содержится в roles, это не все имеющиеся роли, то еще ладно, есть какая-то логика в этом, иначе это мазохизм. Хотя и при таком условии, это не все равно тоже самое будет. :)

jabbascript 09.04.2020 12:03

Это правильная структура. Тут 1на таблица содержит идишники роли и права.
{
"Id": 1,
"RoleId": 1, роль с ид 1
"RightId": 1 право с ид 2
}

Какбы у меня Odata и есть три урла /RoleRight /Role /Rights.

laimas 09.04.2020 13:30

По представленным данным их никак не связать в то, что именно вы хотите получить.

Nexus 09.04.2020 13:32

(() => {
    
    const roleRight = [
        {
            "Id": 1,
            "RoleId": 1,
            "RightId": 1
        },
        {
            "Id": 2,
            "RoleId": 1,
            "RightId": 2
        },
        {
            "Id": 3,
            "RoleId": 2,
            "RightId": 2
        },
        {
            "Id": 4,
            "RoleId": 3,
            "RightId": 1
        },
    ];

    const roles = [
        {
            "Id": 1,
            "Name": "Администратор",
        },
        {
            "Id": 2,
            "Name": "Модератор",
        },
        {
            "Id": 3,
            "Name": "Пользователь",
        },
    ];

    const rights = [
        {
            "Id": 1,
            "Name": "Контакты - Просмотр",
        },
        {
            "Id": 2,
            "Name": "Контакты - Редактирование",
        }
    ];

    const usersRoles = (() => {
        const dictionaries = {
            roles,
            rights
        };
        
        const dictionariesIndexed = Object.keys(dictionaries).reduce((res, key) => {
            res[key] = {};
            
            dictionaries[key].forEach(item => {
                res[key][item.Id] = item;
            });
            
            return res;
        }, {});
        
        const result = roleRight.reduce((res, item) => {
            res[item.RoleId] = {
                Id: item.RoleId,
                Name: dictionariesIndexed.roles[item.RoleId].Name,
                Rights: []
            };
            
            return res;
        }, {});
        
        roleRight.forEach(item => {
            const roleId = item.RoleId;
            const rightId = item.RightId;
            
            result[item.RoleId].Rights.push({
                Id: item.RightId,
                Name: dictionariesIndexed.rights[item.RightId].Name
            });
        });
        
        return Object.values(result);
    })();

    console.log(usersRoles);
    
})();

Nexus 09.04.2020 13:35

У вас данные в базе хранятся "не традиционным" способом.
Загуглите «database relationship types»


Я ошибся, это many2many со сводной таблицей roleRight.
Значения хранятся в 4-й таблице?

По-моему это несколько неудобно.

destus 09.04.2020 13:35

jabbascript,
const roleRight = [
  {
    Id: 1,
    RoleId: 1,
    RightId: 1
  },
  {
    Id: 2,
    RoleId: 1,
    RightId: 2
  },
  {
    Id: 3,
    RoleId: 2,
    RightId: 2
  },
  {
    Id: 4,
    RoleId: 3,
    RightId: 1
  }
];

const roles = [
  {
    Id: 1,
    Name: "Администратор"
  },
  {
    Id: 2,
    Name: "Модератор"
  },
  {
    Id: 3,
    Name: "Пользователь"
  }
];

const rights = [
  {
    Id: 1,
    Name: "Контакты - Просмотр"
  },
  {
    Id: 2,
    Name: "Контакты - Редактирование"
  }
];

console.log(
  roles.map(role => {
    return {
      ...role,
      right: roleRight
        .filter(item => item.RoleId === role.Id)
        .map(item => rights.find(right => right.Id === item.RightId))
    };
  })
);

laimas 09.04.2020 14:01

Nexus,
если roleRight описывает совокупность прав, то все нормально. Я только никак не могу понять - для кого это получается?

Nexus 09.04.2020 14:07

https://jsben.ch/rrIQq Обидно.

Мой код производительнее на большем кол-ве данных.
https://jsben.ch/T9HgF

Nexus 09.04.2020 14:15

Цитата:

Сообщение от laimas
если roleRight описывает совокупность прав, то все нормально.

Список "ролей" и их "прав" без значения "права" не имеет смысла.
А с такой структурой таблиц это будет выглядеть, как прибитый сбоку костыль.
Я это имел ввиду.

Там либо делать связь к таблице role_right, либо придется делать таблицу role_right_value с полями:
- id
- role_id
- right_id
- value

laimas 09.04.2020 14:28

Я не об этом, я о 4-х таблицах - если первая пользователи, вторая роли, третья права, то четвертая вполне может описывать совокупность прав. А вот тут, это что-то непонятное - чего тут получаем?

А вообще, права лучше хранить как битовый набор, это упрощает проверку доступа.


Часовой пояс GMT +3, время: 06:49.