Доступ к данным из двух или более схем в мультитенантном приложении

Мы используем квартирный жемчуг для мультитенантного приложения. Для каждой учетной записи будет поддерживаться отдельная схема. на основе поддомена учетной записи мы перечисляем данные в каждой учетной записи.

В нашем новом требовании есть что-то вроде супераккаунта, где можно посмотреть все данные аккаунта. Например, если на странице списка пользователей выбраны учетная запись 1 и учетная запись 2, пользователи учетных записей 1 и 2 должны быть объединены и просмотрены вместе с возможностью поиска. Есть ли способ объединить более одной схемы данных в квартире? или любые другие заменители


person Aarthi    schedule 05.01.2021    source источник


Ответы (1)


Самый простой подход, который я могу придумать, — это выполнять запросы на объединение по соответствующим схемам. Итак, если у вас есть схемы account_1 и account_2, вы должны сделать что-то вроде SELECT * FROM account_1.users UNION SELECT * FROM account_2.users.

Вы можете, конечно, сделать это динамическим, поэтому, если вы отправите затронутые аккаунты как часть хэша params, у вас может быть что-то вроде этого:

accounts = Account.find(params[:account_ids])
# assuming the schema name is stored in the accounts.tenant_name column:
sql = accounts.map { |account| "SELECT * FROM #{account.tenant_name}.users" }.join(" UNION ")
users = User.find_by_sql(sql)
person Clemens Kofler    schedule 08.01.2021
comment
Спасибо за ответ. Это работает. Но есть ли какой-нибудь вариант в квартире-жемчужине для достижения этого? - person Aarthi; 09.01.2021
comment
И как мы можем различать записи на основе учетных записей? - вариант использования: мне может понадобиться показать информацию об учетной записи пользователя - person Aarthi; 09.01.2021
comment
Зачем вам нужно что-то в жемчужине квартиры для достижения этой цели? Это обычный и простой Rails по умолчанию, без каких-либо дополнительных драгоценных камней, обезьяньих патчей или чего-то еще. Вы могли бы переписать это на Arel, если это больше соответствует вашему вкусу, но опять же: я не вижу причин для этого. - person Clemens Kofler; 10.01.2021
comment
Что касается вашего второго вопроса, то я его не совсем понимаю. Если вас беспокоят разрешения (т. е. не все пользователи должны иметь возможность видеть все учетные записи), вы можете сделать что-то вроде этого: account_ids = params[:account_ids].map(&:to_i) & current_user.account_ids (при условии, что current_user.account_ids включает все учетные записи, к которым имеет доступ current_user). Это предотвращает эксплойты, когда пользователь пытается получить доступ к ресурсам, к которым у него нет доступа. (Примечание: вы можете использовать гем, такой как cancancan или pundit, если хотите более подробно изучить управление разрешениями.) - person Clemens Kofler; 10.01.2021