Rails中的多个数据库连接

时间:2010-01-24 16:34:37

标签: mysql ruby-on-rails ruby activerecord remoting

我正在Rails中编写一个更简单的phpMyAdmin版本;此Web应用程序将在Web服务器上运行(用户可以在其中指示在同一网络上运行的某个数据库服务器的数据库名称,主机名,用户名,密码和端口号)。然后,用户将连接到该计算机,并能够使用UI管理该数据库(添加或删除列,删除表等)。

我有两个相关的问题(你的帮助将极大地帮助我理解如何最好地解决这个问题):

  1. 在传统的Rails应用程序中,我将数据库信息存储在database.yml中,但是在这里我需要动态地完成它。是否有一种很好的方法可以将database.yml文件保留为空并告诉Rails在运行时使用用户提供的连接数据?

  2. 不同的用户可能会连接到不同的数据库(甚至是主机)。我假设我需要跟踪已建立的数据库连接和用户会话之间的关联。实现这一目标的最佳方法是什么?

  3. 提前谢谢。

1 个答案:

答案 0 :(得分:2)

  1. 为了防止Rails使用database.yml初始化ActiveRecord,您只需从config / environment.rb中的:active_record中删除config.frameworks即可。然后,要手动建立连接,请使用ActiveRecord::Base.establish_connection。 (也许ActiveRecord::Base.configurations

    ActiveRecord存储类变量中相关的所有连接。因此,如果要动态创建多个连接,还必须动态子类化ActiveRecord :: Base并在其上调用establish_connection。

    这将是您用于实际管理表的任何子类的抽象基类。要使ActiveRecord意识到这一点,您应该在基类定义中执行self.abstract_class = true

    然后,您要管理的每个表将依次动态地为这个新的抽象基类创建子类。

  2. 这更难,因为当然,你无法真正坚持联系。我能想到的直接解决方案是在会话中存储一个唯一的令牌,并在before_filter中使用它来返回动态的ActiveRecord :: Base子类,您可能会将其存储在某个哈希值中。

    一旦开始运行多个Rails工作进程,这会变得更有趣:

    • 您必须在会话中存储所有数据库连接信息,以便其他工作人员可以使用它。
    • 您可能希望跨工作人员使用一致的唯一令牌,因此对数据库连接参数的组合使用哈希函数。
    • 因为可能用一个令人不知道的令牌调用一个worker,你的子类化和establish_connection逻辑可能会在before_filter中发生。 (例如,而不是登录的那一刻。)
    • 当用户没有正确注销并且会话过期时,你必须找出一些巧妙的垃圾收集连接和类的方法。 (对不起,我不知道这个。)