我正在尝试了解gem是如何工作的,以及如何创建gem以覆盖或添加其他功能到rails 3应用程序。
这是一个错误捕捉宝石,通过http将错误发布到服务器。
要安装它,只需添加gem,然后使用api密钥创建初始化程序。
这部分我到目前为止,但我需要帮助了解gem的执行以及它如何挂钩到rails。
我找到的相关文件是:
https://github.com/airbrake/airbrake/blob/master/lib/airbrake/rails.rb
将方法添加到ActionController
类:
if defined?(ActionController::Base)
ActionController::Base.send(:include, Airbrake::Rails::ActionControllerCatcher)
ActionController::Base.send(:include, Airbrake::Rails::ErrorLookup)
ActionController::Base.send(:include, Airbrake::Rails::ControllerMethods)
ActionController::Base.send(:include, Airbrake::Rails::JavascriptNotifier)
end
在文件的底部执行它:
Airbrake::Rails.initialize
1. You add the gem to your GEMFILE, and call bundle.
2. You run the generator which creates the initializer file:
因此,当我的rails应用程序启动时,它将通过初始化程序。
这是gem实例化的地方,然后在完成解析Airbrake::Rails.initialize
文件的同时在某个地方运行/lib/airbrake/rails.rb
方法吗?
我可以在railtie.rb
文件中看到初始化代码:
https://github.com/airbrake/airbrake/blob/master/lib/airbrake/railtie.rb
config.after_initialize do
Airbrake.configure(true) do |config|
config.logger ||= ::Rails.logger
config.environment_name ||= ::Rails.env
config.project_root ||= ::Rails.root
config.framework = "Rails: #{::Rails::VERSION::STRING}"
end
if defined?(::ActionController::Base)
require 'airbrake/rails/javascript_notifier'
require 'airbrake/rails/controller_methods'
::ActionController::Base.send(:include, Airbrake::Rails::ControllerMethods)
::ActionController::Base.send(:include, Airbrake::Rails::JavascriptNotifier)
end
end
这似乎有意义,因为它在初始化程序运行并设置配置后运行此代码,它将ControllerMethods
等发送到基类。
但这似乎与我之前发布的代码重复,因为在调用ApplicationController
时,事情已经发送到Airbrake::Rails.initialize
文件。
我希望有人可以告诉我事情是如何执行的,以及它是什么顺序,因为我没有看到这个过程如何以明确的方式运作。
答案 0 :(得分:4)
重复的代码在这里支持不同版本的rails。
Rails 2.X
Rails 2.X查找rails/init.rb
以确定gem是否为rails插件。空气制动器包含一行:
require 'airbrake/rails'
您对下一步的总结是正确的:
这是gem实例化的地方,然后是某个地方 该行完成后运行Airbrake :: Rails.initialize方法 解析/lib/airbrake/rails.rb文件?
Rails 3.X
Rails 3.X插件通常从Rails::Railtie
继承,以便能够定义rake任务,插入引导序列或do a lot of other interesting things。
lib/airbrake.rb
中的以下行检查Railtie
类的可用性(相当于检查您是否正在运行rails 3)并定义Airbrake::Railtie
是否为require 'airbrake/railtie' if defined?(Rails::Railtie)
案例:
Railtie
定义Airbrake::Rails.initialize
时,您不必手动运行它(相当于Rails::Railtie
),子类{{1}}足以创建您的插件。
补充阅读
如果您想了解rails 3如何实现其模块化,以下文档将非常有用: