【问题标题】:Has and belongs to many relationship with multiple databases与多个数据库有并属于许多关系
【发布时间】:2010-09-16 02:57:48
【问题描述】:

我有一种情况,我有两个模型,公司和权限,其中公司位于与我的权限数据库不同的数据库中。这是一个拥有和属于很多的关系,因为每个公司可以有很多权限,每个权限可以属于很多公司。

之所以拆分这两个数据库,是因为公司数据库运行一个高需求的生产应用程序,而权限数据库控制另一个应用程序的权限。

使用 rails,它会在与主表相同的数据库中查找连接表。例如,如果我执行 company.permissions,它会在公司数据库中查找 company_permissions。如果我做 permission.companies,它会在权限数据库中查找。

在多个数据库中使用 has 和 belongs to many 关系的最佳解决方案是什么?

【问题讨论】:

    标签: ruby-on-rails ruby database has-and-belongs-to-many


    【解决方案1】:

    有趣的问题。为了我自己的参考,让我尝试在这个问题的上下文中总结Rails Recipe书中提出的解决方案。

    1) 首先在database.yml

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

    2) 制作权限模型调用外部数据库

    class Permission < ActiveRecord::Base
    
      establish_connection :permissions
    
    end 
    

    3) 创建(迁移)一个 Permission Reference 表Permission Id

    4) 使用 PermissionReference 模型作为到 Permission 模型的链接

    class PermissionReference < ActiveRecord::Base
    
      belongs_to :permission
      has_and_belongs_to_many :companies,
                              :join_table => 'companies_permissions',
                              :foreign_key => 'permission_id'
    
    end
    

    5) 最后将 Company 与 Permission 关联

    class Company < ActiveRecord::Base
    
      has_and_belongs_to_many :permissions, 
                              :class_name => 'PermissionReference', 
                              :join_table => 'companies_permissions', 
                              :association_foreign_key => 'permission_id'
    
    end
    

    您可能想考虑通过子类化调用外部数据库的模型进行重构

    class External < ActiveRecord::Base
    
      self.abstract_class = true
      establish_connection :permissions
    
    end
    
    class Permission < External
    end
    

    【讨论】:

    【解决方案2】:

    拥有和属于许多是旧的、笨重的和有问题的。我建议改用 has_many。 您可以使用“:through”选项指定关系表;只需选择您希望它驻留的数据库并创建一个模型来表示它。 http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many

    【讨论】:

    • 我之所以选择这个答案而不是下面更完整的答案是因为有了下面的答案,您仍然需要进行某种同步。使用这种方法,你只需要告诉 ruby​​ 表名。
    【解决方案3】:

    如果公司数据不经常变化,也许你可以将数据同步到权限数据库中,然后自然加入。我继承的 CMS 正在做类似的事情,其中​​用户身份验证位于其自己的数据库中,权限等都存储在那里,并且用户帐户与每个站点的本地数据库同步。通过这种方式,用户帐户可以通过 1 次登录在多个站点之间共享(尤其是用于管理)。

    可能不是最好的,因为涉及到同步。理想情况下,如果您无法将权限移出,您应该只将公司数据存储在权限数据库中。当然,除非你加入其他公司。

    【讨论】:

      猜你喜欢
      • 2017-08-22
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      • 1970-01-01
      • 2012-12-26
      • 2015-11-05
      相关资源
      最近更新 更多