2010 年 2 月 9 日,星期二

插件作者:走向更美好的未来

wycats 发布

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 }

使用 Railtie,但仅在需要时使用

即使您可以期望 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

在 railsplugins.org 上开始对话

为了简化此过程,Engine Yard 已整理出 railsplugins.org。如果您是插件作者,请将插件提交到该网站。您可以告诉用户您是否希望插件在 Rails 3 上运行,用户是否可以在线程安全模式下运行插件,以及它们是否在 JRuby 上运行。

一旦您将插件放到那里,用户就可以表示他们同意或不同意您的插件在运行,并对哪些内容损坏发表评论。您可以回复任何此类评论,并且如果用户只是犯了一个错误,他可以改变主意。当您提交新版本时,该网站将创建一个全新页面,因此有关某个以前版本不起作用的内容的评论不会弄乱当前版本(如果希望,用户仍可以获得以前版本)。

如果我们这样做是正确的,Rails 社区将清楚 Rails 3 中哪些东西可用,哪些不可用。在这里动手吧!