Rails 中的多个数据库连接

发布于 2024-08-18 19:43:16 字数 439 浏览 6 评论 0原文

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

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

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

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

先感谢您。

I'm writing a simpler version of phpMyAdmin in Rails; this web app will run on a web server (where users will be able to indicate the database name, hostname, username, password, and port number of one of the database servers running on the same network). The user will then be connected to that machine and will be able to use the UI to administer that database (add or remove columns, drop tables, etc).

I have two related questions (your help will greatly aid me in understanding how to best approach this):

  1. In a traditional Rails application I would store the database info in database.yml, however here I need to do it dynamically. Is there a good way to leave the database.yml file empty and tell Rails to use the connection data provided by the user at run time instead?

  2. Different users may connect to different databases (or even hosts). I assume that I need to keep track of the association between an established database connection and a user session. What's the best way to achieve this?

Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一袭水袖舞倾城 2024-08-25 19:43:16
  1. 要防止Rails使用database.yml初始化ActiveRecord,您只需从config/environment.rb中的config.frameworks中删除:active_record即可。然后,要手动建立连接,请使用ActiveRecord::Base.built_connection。 (也许ActiveRecord::Base.configurations

    ActiveRecord 将所有与连接相关的内容存储在类变量中。因此,如果您想动态创建多个连接,您还必须动态子类化 ActiveRecord::Base 并对其调用建立连接。

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

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

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

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

    • 您必须将所有数据库连接信息存储在会话中,以便其他工作人员可以使用它。
    • 您可能希望工作人员之间具有一致的唯一令牌,因此请对数据库连接参数的组合使用哈希函数。
    • 因为工作人员可能会使用它还不知道的令牌来调用,所以您的子类化和建立连接逻辑可能会发生在 before_filter 中。 (例如,而不是登录那一刻。)
    • 您必须找出一些巧妙的方法来垃圾收集连接和类,以应对用户未正确注销且会话过期的情况。 (抱歉,我不知道这个。)
  1. To prevent Rails from initializing ActiveRecord using database.yml, you can simply remove :active_record from config.frameworks in config/environment.rb. Then, to manually establish connections, you use ActiveRecord::Base.establish_connection. (And maybe ActiveRecord::Base.configurations)

    ActiveRecord stores everything connection related in class variables. So if you want to dynamically create multiple connections, you also have to dynamically subclass ActiveRecord::Base and call establish_connection on that.

    This will be your abstract base class for any subclass you'll use to actually manage tables. To make ActiveRecord aware of this, you should do self.abstract_class = true within the base class definition.

    Then, each table you want to manage will in turn dynamically subclass this new abstract base class.

  2. This is more difficult, because you can't really persist connections, of course. The immediate solution I can think of is storing a unique token in the session, and use that in a before_filter to get back to the dynamic ActiveRecord::Base subclass, which you'll probably be storing in a hash somewhere.

    This gets more interesting once you start running multiple Rails worker processes:

    • You will have to store all of the database connection information in the session, so other workers can use it.
    • You probably want a consistent unique token across workers, so use a hash function on a combination of database connection parameters.
    • Because a worker may be called with a token it doesn't yet know about, your subclassing and establish_connection logic will probably happen in the before_filter. (Rather than the moment of login, for example.)
    • You will have to figure out some clever way of garbage collecting connections and classes, for when user doesn't properly log out and the session expires. (Sorry, I don't know this one.)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文