ActiveRecord数据库连接的回调?

时间:2014-01-30 01:16:19

标签: mysql ruby-on-rails activerecord ruby-on-rails-4 database-connection

有没有办法挂钩ActiveRecord连接创建?我想在刚创建连接时运行一些代码。

我觉得这可能是在连接上设置MySQL变量的一种方法,因为database.yml中的“变量”对我来说似乎不起作用。 (How to turn off MySQL strict mode in Rails

3 个答案:

答案 0 :(得分:7)

ConnectionAdapter定义了两个回调:checkout(连接)和:checkin(断开连接)。您可以将它用于特定适配器

ActiveRecord::ConnectionAdapters::MysqlAdapter.set_callback :checkout, :after do
  raw_connection.set_your_variables ...
end

或者您可以将ActiveRecord::Base.connection.class用于database.yml

中当前声明的任何适配器

答案 1 :(得分:1)

只需添加到已接受的解决方案中,如果您需要从回调中触发数据库查询,则可以通过以下方式进行:

ActiveRecord::ConnectionAdapters::AbstractAdapter.set_callback :checkout, :before, ->(conn) {
    res = conn.execute('SELECT COUNT(*) from table_name')
    puts "res is #{res.each { |tuple| puts tuple.inspect}}"
}

注意:由于回调是在ActiveRecord :: ConnectionAdapters :: AbstractAdapter上定义的,因此应该在签出任何数据库类型的连接之前执行

正如@Envek在接受的答案的注释中指出的那样,您不应该真正使用ActiveRecord模型,因为您可能会遇到无穷递归的风险。另外(请注意@Envek)请记住,每次使用池连接进行的连接检出都会触发回调,而不仅仅是一次。

最后,很可能您想在Rails中使用它。如果是这样,可以将此代码放在config / initializers文件夹下的文件中。然后,它将在应用程序启动时运行。在要为建立数据库连接的方式添加逻辑的情况下很有用,尤其是当精确操作取决于特定查询的结果时。

答案 2 :(得分:0)

此外,如果您需要在建立连接并检索列信息后配置模型,则可以在模型中重新定义load_schema!类方法。

请参阅:https://github.com/rails/rails/pull/31681#issuecomment-357113030