我有一个案例,我正在尝试利用Padrino使用的数据库配置文件为我正在编写的自定义工作程序,而无需加载Padrino环境,也无需修改现有的数据库配置。简而言之,我想编写我的代码来使用现有的数据库配置代码,而不是修改现有的配置。
有问题的数据库配置文件如下所示:
# This is just here for right now so I can test
# to see if logger is set to anything in DB config
puts "Logger in DB config: #{logger}"
ActiveRecord::Base.configurations[:development] = {
:adapter => 'sqlite3',
:database => Padrino.root('db', "app_development.db") }
ActiveRecord::Base.logger = logger
ActiveRecord::Base.include_root_in_json = true
ActiveRecord::Base.store_full_sti_class = true
ActiveSupport.use_standard_json_time_format = true
ActiveSupport.escape_html_entities_in_json = false
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Padrino.env])
我的自定义工作人员如下所示:
ROOT = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift(ROOT)
require 'active_record'
require 'logger'
# Mock Padrino module with methods used by database config file
module Padrino
def self.root(*args)
return File.expand_path(File.join("#{ROOT}/..", *args))
end
def self.env
return :development
end
end
module Worker
class << self
attr_accessor :logger
def init
@logger = Logger.new(STDOUT)
@logger.level = Logger::DEBUG
require "#{ROOT}/../config/database"
end
end
end
Worker.init
当我在我的工作人员中需要数据库配置文件时,出现以下错误:
/home/user/devel/app/config/database.rb:3:in `<top (required)>': undefined local variable or method `logger' for main:Object (NameError)
from /home/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:55:in `require'
from /home/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:55:in `require'
from worker.rb:26:in `init'
from worker.rb:31:in `<main>'
鉴于此,我将Worker#init
函数修改为以下内容:
def init
@logger = Logger.new(STDOUT)
@logger.level = Logger::DEBUG
Object.send(:define_method, :logger, lambda { @logger })
puts "Logger in Worker module: #{logger}"
require "#{ROOT}/../config/database"
end
此更改导致以下输出:
Logger in Worker module: #<Logger:0x9505088>
Logger in DB config:
我认为这意味着@logger
不在数据库配置文件的范围内,即使我在Object上定义记录器方法时使用lambda。
奇怪的是,如果我从Object.send
函数中提取Worker#init
代码行,而是在我调用Worker.init
之前调用它,如下所示,我得到以下结果。< / p>
Object.send(:define_method, :logger, lambda { Worker.logger })
Worker.init
结果
Logger in Worker module: #<Logger:0x81bc8b4>
Logger in DB config: #<Logger:0x81bc8b4>
有人可以向我解释为什么如果我在Object.send
函数中进行Worker#init
调用它不会像在工作模块外部那样工作吗?
答案 0 :(得分:0)
在第一个示例中,您尝试使用未定义的变量'logger',正如您可以从错误消息中看到的那样。尝试以这种方式使用记录器功能:
ActiveRecord::Base.logger = Logger.new(STDOUT)