Я хотел бы сделать предложение по варианту 1, которое может избежать некоторой его критики.Вместо использования логических значений для каждого возможного разрешения, вместо этого используйте битовую маску.
Сначала пример
(liability_mask INT)
def Roles
RESPONSIBILITES = [ :switchboard, :content_manager, :network_administrator, :financial_manager, :receives_contact_emails ]
def responsibilites=(responsibilites)
self.responsible_mask = ([*responsibilites].map(&:to_sym) & RESPONSIBILITES).map { |r| 2**RESPONSIBILITES.index(r) }.sum
end
def responsibilites
RESPONSIBILITES.reject { |r| ((responsible_mask || 0) & 2**RESPONSIBILITES.index(r)).zero? }
end
def responsibilites_symbols
responsibilites.map(&:to_sym)
end
def responsible?(responsibility="none")
responsibilities_symbols.includes?(responsibility.to_sym)
end
end
Легко добавить большеобязанности в любое время.
А теперь почему?
На мой взгляд, это лучшая практика.Я не вижу причины, по которой я бы создал форму, чтобы добавить еще одну ответственность (или привилегию в вашем случае), не добавляя также хуки в моем коде, чтобы использовать эту ответственность.Мне нужна только эта информация, чтобы определить, следует ли мне разрешить функциональность;у него нет другой цели.Конечно, я все еще хочу, чтобы администратор мог создавать роли и назначать обязанности для этой роли, но это всегда будет тот фиксированный набор.
Это также делает запросы SQL более сложными, добавляя еще одно объединение.Помедленнее.Труднее в отладке.
Трудно помнить, что нужно создавать эту таблицу статических данных при развертывании на другом сервере.