Доктрина Symfony сериализует глубокие отношения - PullRequest
0 голосов
/ 28 мая 2018

Я разрабатываю API, используя Symfony 4, с картой сущностей, подобной этой (упрощенно):

simplified database structure

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

Я знаю, что нужно сделать, чтобы, например, вернуть все учетные записи с их проектами через аннотации (ORM, Serializer), ...).

Но я не знаю, как вернуть все Учетные записи с каждой Операцией, которую может выполнить Пользователь.Я хотел бы получить ответ, подобный этому:

[{
    "id": 1,
    "name": "Account 1",
    "operations": [
        "account.list",
        "account.edit",
        "account.grant"
    ]
}, {
    "id": 2,
    "name": "Account 2",
    "operations": [
        "account.list"
    ]
}]

Что я должен сделать:

  • Добавить функцию Account :: getOperations (), которая вызывает OperationRepository :: findAllByAccount ()?
  • Вставить OperationRepository в контроллер и вручную извлечь Operations и назначить их свойству в классе Accounts, не сопоставленном ORM?

Я немного растерялся там.Никогда раньше не работал с ORM ...

Спасибо.


Редактировать: это то, что я хотел бы сделать на простом PHP (не тестировано):

public function findUserAccountsWithPermissions(int $userId)
{
    $sql = "
      SELECT
        a.id,
        a.name,
        o.code
      FROM Permission p
        INNER JOIN Account a ON a.id = p.accountId
        INNER JOIN Role_Operation ro ON ro.roleId = p.roleId
        INNER JOIN Operation o ON o.id = ro.operationId
      WHERE
        p.userId = :userId
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(':userId', $userId, PDO::PARAM_INT);
    $stmt->execute();

    $accounts = [];

    while ($row = $stmt->fetch()) {
        $accountId = (int)$row['id'];

        if (!isset($accounts[$accountId])) {
            $accounts[$accountId] = [
                'id'         => $accountId,
                'name'       => $row['name'],
                'operations' => [],
            ];
        }

        $accounts[$accountId]['operations'][] = $row['code'];
    }

    return array_values($accounts);
}

1 Ответ

0 голосов
/ 29 мая 2018

Полагаю, вы ищете такой запрос

Внутри PermissionRepository (я полагаю, у вас есть вся информация о сопоставлении)

public function findOperationAccountForUser(User $user)
    {
        $qb = $this->createQueryBuilder('p');

        $qb->leftJoin('p.role', 'r')
            ->leftJoin('r.operations', 'op')
            ->leftJoin('p.account', 'a')
            ->where($qb->expr()->eq('p.user', ':user'))
            ->setParameter('user', $user)
            ->select('op.code, op.name,r.name, a.name,...');//or exclude for select all fields

        return $qb->getQuery()->getResult();//or arrayResult as you want
    }

Надеюсь, это поможет!

...