Rails 3 中一些最大的更改在于 Rails 对插件的行为的预期。
如果插件有依赖项,请将其制作成 Gem 并让用户使用 Gemfile 安装它。这将确保 Bundler 适当地计算依赖项以及用户应用程序的任何其他依赖项。
如果您需要覆盖 ActionController、ActiveRecord 或其他 Rails 框架,请先要求提供它们,然后覆盖。不要假设 Rails 会在“正确”的时间要求提供 Gem 插件,而应假设用户会非常早地要求提供插件。
这为您提供了在初始化过程中更早进行挂钩的机会,但也意味着您应该明确要求提供所需的依赖项。
# in your_lib.rb
require "active_record"
require "your_lib/extensions"
ActiveRecord::Base.class_eval { include YourLib::Extensions }
即使您可以期望 Gem 非常早加载,仍可能需要挂钩到初始化过程的后期。如果您这样做,请从 `Rails::Railties` 继承。在 Railtie 内,您可以声明 Rails 在运行 Rakefile、指定初始化块、将订阅者添加到通知系统以及指定加载生成器时应运行的块。
class TestingFu < Rails::Railtie
# This creates a config.my_plugin in the user's Application
railtie_name :testing_fu
rake_task do
load "testing_fu/tasks.rake"
end
# specify the default generators for test frameworks
config.generators.test_framework :testing_fu
# you can also specify :before or :after to ensure that
# your initializer block runs before or after another
# initializer block
initializer :setup_my_plugin do |app|
# in here, I have access to the user's application,
# which gives me access to app.config
end
end
确保要求提供您打算扩展的任何 railtie。例如,如果您想在 ActionController 中定义的初始化程序之前运行一个初始化程序,请要求提供“action_controller/railtie”
也就是说,如果您的代码不需要挂钩到 Rails 生命周期中的任何部分,请不要使用 Railtie。如果可能,只需创建一个标准的 Ruby 库,要求提供需要覆盖的 Rails 部分即可。
插件中的引擎(`vendor/plugins`)在 Rails 2 中的工作方式与在 Rails 3 中的工作方式相同。在 Gem 中,您需要提供一个 `Rails::Engine` 子类
# lib/my_engine.rb module MyEngine class Engine < ::Rails::Engine engine_name :my_engine end end
将您的应用程序目录放在 lib 目录旁边,Rails 将选中该目录。您可以在此处一处阅读 Railte、Engine、Plugin 和 Application 的文档:https://gist.github.com/af7e572c2dc973add221
为了简化此过程,Engine Yard 已整理出 railsplugins.org。如果您是插件作者,请将插件提交到该网站。您可以告诉用户您是否希望插件在 Rails 3 上运行,用户是否可以在线程安全模式下运行插件,以及它们是否在 JRuby 上运行。
一旦您将插件放到那里,用户就可以表示他们同意或不同意您的插件在运行,并对哪些内容损坏发表评论。您可以回复任何此类评论,并且如果用户只是犯了一个错误,他可以改变主意。当您提交新版本时,该网站将创建一个全新页面,因此有关某个以前版本不起作用的内容的评论不会弄乱当前版本(如果希望,用户仍可以获得以前版本)。
如果我们这样做是正确的,Rails 社区将清楚 Rails 3 中哪些东西可用,哪些不可用。在这里动手吧!