A et appartient à de nombreuses relations avec plusieurs bases de données
-
06-07-2019 - |
Question
J'ai deux modèles, des entreprises et des autorisations, dans lequel les entreprises se trouvent dans une base de données distincte de celle de mes autorisations. Ceci est une relation a et appartient à de nombreuses relations car chaque entreprise peut avoir plusieurs autorisations et chaque autorisation peut appartenir à plusieurs entreprises.
La division des deux bases de données s'explique par le fait que la base de données de la société exécute une application de production très sollicitée et que la base de données des autorisations contrôle les autorisations d'une autre application.
Avec rails, il recherche la table de jointure dans la même base de données que la table primaire. Par exemple, si je pratique company.permissions, il recherche dans company_permissions. Si je le fais avec permission.companies, cela se trouve dans la base de données des permissions.
Quelle est la meilleure solution pour utiliser un objet appartenant à de nombreuses relations avec plusieurs bases de données?
La solution
a et appartient à beaucoup est vieux, maladroit et problématique. Je recommande d'utiliser has_many à la place. Vous pouvez spécifier la table de relations avec les options ":: through " option; il suffit de choisir la base de données dans laquelle vous voulez qu'elle réside et de créer un modèle pour la représenter. http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many
Autres conseils
Question intéressante. Pour ma propre référence, permettez-moi de tenter de résumer la solution proposée dans le livre Recette Rails dans le contexte de cette question.
1) Ajoutez d’abord dans database.yml
permissions:
adapter: mysql
database: permissions
username: root
password:
socket: /tmp/mysql.sock
2) Créer un modèle d’autorisation pour appeler une base de données externe
class Permission < ActiveRecord::Base
establish_connection :permissions
end
3) Créez (migrez) une table de référence des autorisations avec la colonne ID d'autorisation
4) Utilisez le modèle PermissionReference comme lien vers le modèle Permission
.class PermissionReference < ActiveRecord::Base
belongs_to :permission
has_and_belongs_to_many :companies,
:join_table => 'companies_permissions',
:foreign_key => 'permission_id'
end
5) Enfin, associez la société à la permission
class Company < ActiveRecord::Base
has_and_belongs_to_many :permissions,
:class_name => 'PermissionReference',
:join_table => 'companies_permissions',
:association_foreign_key => 'permission_id'
end
Vous pouvez envisager de refactoriser le modèle en sous-classant les modèles appelant une base de données externe
class External < ActiveRecord::Base
self.abstract_class = true
establish_connection :permissions
end
class Permission < External
end
Si les données de l'entreprise ne changent pas très souvent, vous pourriez peut-être synchroniser les données dans la base de données des autorisations, puis faites votre jointure naturellement. Un CMS dont j'ai hérité agit de la manière suivante: l'authentification de l'utilisateur se trouve dans sa propre base de données. Les autorisations, etc., sont stockées dans cette base. Les comptes d'utilisateurs sont synchronisés sur la base de données locale de chaque site. De cette manière, les comptes d’utilisateur peuvent être partagés (en particulier pour l’administration) sur plusieurs sites avec une seule connexion.
Peut ne pas être le meilleur, car une synchronisation est impliquée. Idéalement, vous devriez simplement stocker les données de la société dans la base de données des autorisations si vous ne pouvez pas les déplacer. À moins bien sûr que vous ne rejoigniez la compagnie ailleurs.