【问题标题】:Multiple database connections in RailsRails 中的多个数据库连接
【发布时间】:2011-01-08 19:50:03
【问题描述】:
我正在 Rails 中编写一个更简单的 phpMyAdmin 版本;此 Web 应用程序将在 Web 服务器上运行(用户将能够指示在同一网络上运行的数据库服务器之一的数据库名称、主机名、用户名、密码和端口号)。然后,用户将连接到该计算机并能够使用 UI 来管理该数据库(添加或删除列、删除表等)。
我有两个相关的问题(您的帮助将极大地帮助我理解如何最好地解决这个问题):
在传统的 Rails 应用程序中,我会将数据库信息存储在 database.yml 中,但是在这里我需要动态地进行。有没有什么好的方法可以让 database.yml 文件为空并告诉 Rails 使用用户在运行时提供的连接数据?
不同的用户可能会连接到不同的数据库(甚至是主机)。我假设我需要跟踪已建立的数据库连接和用户会话之间的关联。实现这一目标的最佳方法是什么?
提前谢谢你。
【问题讨论】:
标签:
mysql
ruby-on-rails
ruby
activerecord
remoting
【解决方案1】:
-
要防止 Rails 使用 database.yml 初始化 ActiveRecord,您可以简单地从 config/environment.rb 中的 config.frameworks 中删除 :active_record。然后,要手动建立连接,请使用ActiveRecord::Base.establish_connection。 (也许ActiveRecord::Base.configurations)
ActiveRecord 将所有与连接相关的内容存储在类变量中。所以如果你想动态创建多个连接,你还必须动态地继承 ActiveRecord::Base 并在其上调用建立连接。
这将是您用于实际管理表的任何子类的抽象基类。要让 ActiveRecord 意识到这一点,您应该在基类定义中使用self.abstract_class = true。
然后,您要管理的每个表将依次动态地继承这个新的抽象基类。
-
这更难,因为你当然不能真正保持连接。我能想到的直接解决方案是在会话中存储一个唯一令牌,并在 before_filter 中使用它来返回动态 ActiveRecord::Base 子类,您可能会将其存储在某个哈希值中。
一旦您开始运行多个 Rails 工作进程,这会变得更有趣:
- 您必须在会话中存储所有数据库连接信息,以便其他工作人员可以使用它。
- 您可能希望在工作人员之间使用一致的唯一令牌,因此请对数据库连接参数组合使用哈希函数。
- 因为可能会使用它还不知道的令牌调用工作程序,所以您的子类化和建立连接逻辑可能会发生在 before_filter 中。 (例如,而不是登录的那一刻。)
- 您必须想出一些巧妙的方法来收集连接和类的垃圾,以防用户未正确注销并且会话到期。 (对不起,我不知道这个。)