Relacionamentos muitos-para-muitos são a única opção viável aqui. Há uma razão pela qual eles chamam de banco de dados relacional.
Por quê?
- As associações não são tão caras.
- Múltiplas colunas - O número de colunas em suas tabelas será ludicris e será um verdadeiro inferno para desenvolvedores. Como cada recurso adiciona uma migração, a quantidade de rotatividade em sua base de código será boba.
- Coluna de matriz - Usar uma coluna de matriz pode parecer uma alternativa atraente até você perceber que, na verdade, é apenas uma melhoria marginal em relação ao preenchimento de coisas em uma string separada por vírgulas. você não tem integridade referencial e nenhum dos benefícios de organização de código que vêm de ter modelos que representam as entidades em seu aplicativo.
Ah, e toda vez que um recurso é removido, você precisa atualizar cada um desses mais de 500 mil usuários. VS apenas usando CASCADE.
class Feature
has_many :user_features
has_many :users, through: :user_features
end
class UserFeature
belongs_to :user
belongs_to :feature
end
class User
has_many :user_features
has_many :features, through: :user_features
def has_feature?(name)
features.exist?(name: name)
end
end