2008-10-08 11 views
7

J'ai une situation où j'ai deux modèles, entreprises et autorisations, où les entreprises sont dans une base de données séparée de ma base de données d'autorisations. Ceci est un a et appartient à beaucoup de relation parce que chaque entreprise peut avoir beaucoup d'autorisations et chaque permission peut appartenir à beaucoup d'entreprises.A et appartient à de nombreuses relations avec plusieurs bases de données

La raison pour laquelle les deux bases de données sont partagées est que la base de données de l'entreprise exécute une application de production à forte demande et que la base de données d'autorisations contrôle les autorisations pour une autre application. Avec les rails, il recherche la table de jointure dans la même base de données que la table primaire. Par exemple, si je fais company.permissions, il apparaît dans la base de données de l'entreprise pour company_permissions. Si je fais permission.companies, il regarde dans la base de données des autorisations.

Quelle est la meilleure solution pour utiliser un a et appartient à de nombreuses relations avec plusieurs bases de données?

Répondre

5

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 relation avec l'option ": through"; 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

+0

La raison pour laquelle j'ai choisi cette réponse sur la réponse plus complète ci-dessous est parce qu'avec la réponse ci-dessous, vous devez encore faire une sorte de synchronisation. Avec cette méthode, il suffit de dire à ruby ​​le nom de la table. – Steropes

1

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 d'autorisations, puis effectuez votre jointure naturellement. Un CMS que j'ai hérité fait quelque chose comme ça où l'authentification de l'utilisateur est dans sa propre base de données, et les permissions et autres sont stockées là, et les comptes d'utilisateurs sont synchronisés avec la base de données locale pour chaque site. De cette façon, les comptes d'utilisateurs pourraient être partagés (en particulier pour l'administration) entre plusieurs sites avec 1 connexion. Peut ne pas être le meilleur car une synchronisation est impliquée. Idéalement, vous devriez juste stocker les données de l'entreprise dans les autorisations db si vous ne pouvez pas déplacer les autorisations. Sauf si vous vous joignez à une entreprise ailleurs.

6

Question intéressante. Pour ma propre référence, permettez-moi de résumer la solution proposée dans le livre Rails Recipe dans le contexte de cette question.

1) D'abord ajouter la base de données .YML

permissions: 
    adapter: mysql 
    database: permissions 
    username: root 
    password: 
    socket: /tmp/mysql.sock 

2) Marque Modèle d'autorisation d'appeler base de données externe

class Permission < ActiveRecord::Base 

    establish_connection :permissions 

end 

3) Créer (migration) une autorisation table de référence avec Permission Id colonne

4) Utilisation PermissionReference en tant que lien vers Autorisation modèle

class PermissionReference < ActiveRecord::Base 

    belongs_to :permission 
    has_and_belongs_to_many :companies, 
          :join_table => 'companies_permissions', 
          :foreign_key => 'permission_id' 

end 

5) Société associé Enfin à autorisation

class Company < ActiveRecord::Base 

    has_and_belongs_to_many :permissions, 
          :class_name => 'PermissionReference', 
          :join_table => 'companies_permissions', 
          :association_foreign_key => 'permission_id' 

end 

Vous voudrez peut-être envisager de refactoring par le sous-classement des modèles qui appelle une base de données externe

class External < ActiveRecord::Base 

    self.abstract_class = true 
    establish_connection :permissions 

end 

class Permission < External 
end 
+0

Cette réponse semble très similaire à cette page: https://calshare.berkeley.edu/sites/AS/Web_Apps/ruby/Wiki%20Pages/Connecting%20to%20Multiple%20Databases.aspx – Steropes

+1

Ouais cette page est fondamentalement une copie de la recette 15 trouvé dans le livre de recettes Rails sur lequel ma réponse était basée. :) – JasonOng

Questions connexes