Как я выполняю запросы после соединения с БД в направляющих?

У меня есть определенные функции инициализации, которые я использую для установки аудита, входящего в систему сторона сервера БД (т.е., не направляющие) в PostgreSQL. По крайней мере один должен быть выпущен (установка текущего пользователя) прежде, чем вставить данные в или обновить любую из контролируемых таблиц, или иначе целый запрос перестанет работать эффектно.

Я могу легко назвать их каждым разом прежде, чем работать, любой сохраняет операцию в коде, но DRY заставляет меня думать, что мне нужно повторить код в как можно меньшем количестве мест, особенно так как это отличается значительно от идеала агностицизма базы данных. В настоящее время я пытаюсь переопределить ActiveRecord:: основа establish_connection в инициализаторе для установки его так, чтобы запросы были выполнены, как только я соединяюсь автоматически, но это не ведет себя, поскольку я ожидаю это к. Вот код в инициализаторе:

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 ни на какую стоящую информацию, и я также не могу инвертировать компиляцию).

Однако код никогда, кажется, не называют, потому что любая попытка выполнить сохранение или обновление на объекте базы данных перестала работать, как я предсказал ранее. Если это не надлежащий способ сразу выполнить код на соединении с базой данных, то, что?

6
задан sycobuny 25 March 2010 в 21:12
поделиться

3 ответа

Rails использует пул соединений, поэтому лучше всего использовать alias_method_chain для 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
3
ответ дан 17 December 2019 в 18:12
поделиться

Знаете ли вы, что ваш инициализатор вызывается до установления соединения с базой данных?

Без достоверной информации о том, что может быть не так, я бы воспользовался тем фактом, что источник ActiveRecord находится на моем жестком диске.

Погрузитесь в базовый класс и сделайте небольшую отладку, чтобы увидеть, когда вызывается ActiveRecord install_connection относительно того, когда вызывается ваш инициализатор. Либо так, либо просто включите дополнительную подробную отладку.

0
ответ дан 17 December 2019 в 18:12
поделиться

С точки зрения написания кода для перехвата вызовов и инициализаций базы данных rails, вы можете использовать код из db-charmer в качестве шаблон. Он демонстрирует ряд интересных способов взаимодействия с ActiveRecord, и один из них, вероятно, будет делать то, что вы хотите.

0
ответ дан 17 December 2019 в 18:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: