У меня есть определенные функции инициализации, которые я использую для установки аудита, входящего в систему сторона сервера БД (т.е., не направляющие) в 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 ни на какую стоящую информацию, и я также не могу инвертировать компиляцию).
Однако код никогда, кажется, не называют, потому что любая попытка выполнить сохранение или обновление на объекте базы данных перестала работать, как я предсказал ранее. Если это не надлежащий способ сразу выполнить код на соединении с базой данных, то, что?
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
Знаете ли вы, что ваш инициализатор вызывается до установления соединения с базой данных?
Без достоверной информации о том, что может быть не так, я бы воспользовался тем фактом, что источник ActiveRecord находится на моем жестком диске.
Погрузитесь в базовый класс и сделайте небольшую отладку, чтобы увидеть, когда вызывается ActiveRecord install_connection относительно того, когда вызывается ваш инициализатор. Либо так, либо просто включите дополнительную подробную отладку.
С точки зрения написания кода для перехвата вызовов и инициализаций базы данных rails, вы можете использовать код из db-charmer в качестве шаблон. Он демонстрирует ряд интересных способов взаимодействия с ActiveRecord, и один из них, вероятно, будет делать то, что вы хотите.