【问题标题】:How do I execute queries upon DB connection in Rails?如何在 Rails 中对数据库连接执行查询?
【发布时间】:2010-03-25 21:12:15
【问题描述】:

我有一些初始化函数,用于在 PostgreSQL 的数据库服务器端(即,不是 rails)设置审计日志。在将数据插入或更新任何已审计的表之前,必须发出至少一个(设置当前用户),否则整个查询将失败。

每次在代码中运行任何保存操作之前,我都可以轻松地调用它们,但是 DRY 让我认为我应该在尽可能少的地方重复代码,特别是因为这与数据库不可知论的理想有很大不同。目前我正在尝试在初始化程序中覆盖 ActiveRecord::Base.establish_connection 以对其进行设置,以便在我自动连接后立即运行查询,但它的行为不像我预期的那样。这是初始化程序中的代码:

类 ActiveRecord::Base # 扩展类方法,而不是实例方法 类 sycobuny:~/rails$ ruby​​ 脚本/服务器 => 启动 WEBrick => Rails 2.3.5 应用程序从 http://0.0.0.0:3000 开始 将自定义建立连接加载到 ActiveRecord::Base

这不会给我任何错误,不幸的是我无法检查该方法内部的样子(我使用的是 ActiveRecord::Base.method(:establish_connection),但显然每次都会创建一个新的 Method 对象它被调用,这似乎毫无价值,因为我无法检查 object_id 是否有任何有价值的信息,我也无法反转编译)。

但是,代码似乎永远不会被调用,因为任何对数据库对象运行保存或更新的尝试都会失败,正如我之前预测的那样。如果这不是在连接到数据库时立即执行代码的正确方法,那是什么?

【问题讨论】:

    标签: ruby-on-rails postgresql database-connection


    【解决方案1】:

    Rails 使用连接池,所以最好的办法是为 ActiveRecord::ConnectionAdapters::ConnectionPool#new_connection 使用 alias_method_chain

    module ActiveRecord
      Module ConnectionAdapters
        class ConnectionPool
          alias_method_chain :new_connection, :my_stuff
          private
          def new_connection_with_my_stuff
            c = new_connection_without_my_stuff
            # Do your stuff with 
            # c.exec(<your sql command>)
            c
          end
        end
      end
    end
    

    【讨论】:

    • 我相信 alias_method_chain 需要在方法声明后运行。
    • alias_method_chain 确实需要在方法声明后调用,否则找不到方法。此外,运行 c 的方法是执行,而不是 exec(我相信它给我的错误是 exec 是私有的)。但除此之外,这解决了我遇到的问题。谢谢!
    • 在这种情况下如何获取当前用户
    【解决方案2】:

    你知道你的初始化器在数据库连接建立之前被调用了吗?

    如果没有关于可能出错的权威信息,我会利用 ActiveRecord 的源在我的硬盘上这一事实。

    深入基类并进行一些调试,以查看 ActiveRecord 建立连接的调用时间相对于初始化程序的调用时间。或者只是打开额外的详细调试。

    【讨论】:

      【解决方案3】:

      在编写代码以挂钩 Rails 数据库调用和初始化方面,您可能希望使用来自 db-charmer 的代码作为模板。它演示了许多与 ActiveRecord 交互的有趣方式,其中一种可能会满足您的需求。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-05
        • 2018-09-23
        • 2022-11-14
        • 1970-01-01
        • 2018-05-15
        • 1970-01-01
        相关资源
        最近更新 更多