添加一个方法挂钩,在模型上的任何activerecord方法之后触发

时间:2014-03-26 16:19:57

标签: ruby-on-rails ruby postgresql

我们的一个用例涉及在Drb上发布活动记录模型。看起来当我们这样做时,我们无意中将连接检出,因此我们会收到AR超时。

我认为这是因为活动记录代码中的这条评论:

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html

特别是

  

"与Active Record 2.1一样,只需使用ActiveRecord :: Core#连接即可   和更早的(预连接池)。最后,当你完成了   连接,并希望它返回到游泳池,你   调用ActiveRecord :: Base.clear_active_connections!。这将是   与Active一起使用时Active Record的默认行为   Action Pack的请求处理周期。"

当我们通过Drb访问模型时,我们不会经历请求周期,因此连接不会被重新检入。

同一文档建议我们需要手动检查这些连接 - 我需要的是一种挂钩已发布模型上的所有方法并调用" ActiveRecord :: Base.clear_active_connections"然后。

class Foo < ActiveRecord::Base

   #I need this method to be called after every method on this class!
   def close_connections
     ActiveRecord::Base.close_active_connections
   end

end

手动关闭连接并不是一个选项,因为有数万行代码,我需要去添加&#34;关闭连接&#34;每一个人之后!

2 个答案:

答案 0 :(得分:1)

您可以在类定义的末尾添加此代码段。

(instance_methods - Class.new.methods).each do |method|
   define_method "#{method}_with_close_connections" do |*args, &block|
     self.send "#{method}_without_close_connections", *args, &block
     ActiveRecord::Base.close_active_connections
   end
   alias_method_chain method, :close_connections
end

然而,非常不推荐。您可能应该找到另一种解决方案。

答案 1 :(得分:0)

一个可能的解决方案是使用观察者 - http://api.rubyonrails.org/v3.2.13/classes/ActiveRecord/Observer.html

但是,您需要为每个模型提供观察者。

在走这条路之前,我会彻底评估您的实施并找到更好的方式来访问连接池。