如何在Rails中的DB连接上执行查询? [英] How do I execute queries upon DB connection in Rails?

查看:171
本文介绍了如何在Rails中的DB连接上执行查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have certain initializing functions that I use to set up audit logging on the DB server side (ie, not rails) in PostgreSQL. At least one has to be issued (setting the current user) before inserting data into or updating any of the audited tables, or else the whole query will fail spectacularly.

在代码中运行任何保存操作之前,我可以很容易地调用这些代码,但是DRY使我认为我应该尽可能在尽可能少的地方重复代码,特别是因为它与数据库的理想有很大的不同。不可知论。目前,我试图重写ActiveRecord :: Base.establish_connection在初始化器中设置它,使查询一旦我自动连接运行,但它不按预期的行为。下面是初始化器中的代码:

I can easily call these every time before running any save operation in the code, but DRY makes me think I should have the code repeated in as few places as possible, particularly since this diverges greatly from the ideal of database agnosticism. Currently I'm attempting to override ActiveRecord::Base.establish_connection in an initializer to set it up so that the queries are run as soon as I connect automatically, but it doesn't behave as I expect it to. Here is the code in the initializer:


class ActiveRecord::Base
  # extend the class methods, not the instance methods
  class << self
    alias :old_establish_connection :establish_connection # hide the default

    def establish_connection(*args)
      ret = old_establish_connection(*args) # call the default

      # set up necessary session variables for audit logging
      # call these after calling default, to make sure conn is established 1st
      db = self.class.connection
      db.execute("SELECT SV.set('current_user', 'test@localhost')")
      db.execute("SELECT SV.set('audit_notes', NULL)") # end "empty variable" err

      ret # return the default's original value
    end
  end
end

puts "Loaded custom establish_connection into ActiveRecord::Base"




sycobuny:~/rails$ ruby script/server 
=> Booting WEBrick
=> Rails 2.3.5 application starting on http://0.0.0.0:3000
Loaded custom establish_connection into ActiveRecord::Base

给我任何错误,不幸的是我不能检查的方法看起来像内部(我使用ActiveRecord :: Base.method(:establish_connection),但显然,每次被调用时创建一个新的方法对象,这看起来毫无价值因为我不能检查object_id任何有价值的信息,我也不能逆转编译)。

This doesn't give me any errors, and unfortunately I can't check what the method looks like internally (I was using ActiveRecord::Base.method(:establish_connection), but apparently that creates a new Method object each time it's called, which is seemingly worthless cause I can't check object_id for any worthwhile information and I also can't reverse the compilation).

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

However, the code never seems to get called, because any attempt to run a save or an update on a database object fails as I predicted earlier. If this isn't a proper way to execute code immediately on connection to the database, then what is?

推荐答案

Rails使用连接pooling,所以你最好的打算是使用一个alias_method_chain为ActiveRecord :: ConnectionAdapters :: ConnectionPool#new_connection

Rails uses connection pooling, so your best bet is to use an alias_method_chain for ActiveRecord::ConnectionAdapters::ConnectionPool#new_connection

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

这篇关于如何在Rails中的DB连接上执行查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆