Viele-zu-viele-Beziehungen sind hier die einzig praktikable Option. Es gibt einen Grund, warum sie es eine relationale Datenbank nennen.
Wieso den?
- Joins sind eigentlich gar nicht so teuer.
- Mehrere Spalten - Die Anzahl der Spalten in Ihren Tabellen wird lächerlich sein und es wird eine wahre Entwicklerhölle sein. Da jedes Feature eine Migration hinzufügt, wird die Menge an Abwanderung in Ihrer Codebasis albern sein.
- Array-Spalte - Die Verwendung einer Array-Spalte mag wie eine attraktive Alternative erscheinen, bis Sie feststellen, dass dies eigentlich nur eine geringfügige Verbesserung gegenüber dem Füllen von Dingen in eine durch Kommas getrennte Zeichenfolge ist. Sie haben keine referenzielle Integrität und keinen der Vorteile der Codeorganisation, die sich aus Modellen ergeben, die die Entitäten in Ihrer Anwendung darstellen.
Oh, und jedes Mal, wenn eine Funktion entfernt wird, müssen Sie jeden dieser über 500.000 Benutzer aktualisieren. VS nur mit 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