Rails::Railtie
是 Rails 框架的核心,它提供了一些钩子来扩展 Rails 或修改初始化过程。
Rails 的每个主要组件(Action Mailer、Action Controller、Active Record 等)都实现了一个 railtie。它们各自负责自己的初始化。这使得 Rails 本身不存在任何组件钩子,允许其他组件替换 Rails 默认的任何组件。
开发 Rails 扩展不需要实现 railtie,但是如果你需要在启动期间或之后与 Rails 框架进行交互,那么就需要 railtie。
例如,执行以下任何操作的扩展都需要 railtie
-
创建初始化器
-
为应用程序配置 Rails 框架,例如设置生成器
-
向环境添加
config.*
键 -
使用
ActiveSupport::Notifications
设置订阅者 -
添加 Rake 任务
创建 Railtie
要使用 railtie 扩展 Rails,请创建一个 Rails::Railtie
的子类。这个类必须在 Rails 启动过程中加载,通常称为 MyNamespace::Railtie
。
以下示例演示了一个可以与 Rails 一起使用或不使用 Rails 的扩展。
# lib/my_gem/railtie.rb
module MyGem
class Railtie < Rails::Railtie
end
end
# lib/my_gem.rb
require "my_gem/railtie" if defined?(Rails::Railtie)
初始化器
要从你的 railtie 向 Rails 启动过程添加一个初始化步骤,只需使用 initializer
宏定义初始化代码
class MyGem::Railtie < Rails::Railtie
initializer "my_gem.configure_rails_initialization" do
# some initialization behavior
end
end
如果指定,块也可以接收应用程序对象,以防你希望访问某些特定于应用程序的配置,例如中间件
class MyGem::Railtie < Rails::Railtie
initializer "my_gem.configure_rails_initialization" do |app|
app.middleware.use MyGem::Middleware
end
end
最后,你也可以将 :before
和 :after
作为选项传递给 initializer
,以防你希望将其与初始化过程中的特定步骤耦合。
配置
Railtie 可以访问一个 config 对象,该对象包含所有 railtie 和应用程序共享的配置
class MyGem::Railtie < Rails::Railtie
# Customize the ORM
config.app_generators.orm :my_gem_orm
# Add a to_prepare block which is executed once in production
# and before each request in development.
config.to_prepare do
MyGem.setup!
end
end
加载 Rake 任务和 Generators
如果你的 railtie 包含 Rake 任务,你可以通过 rake_tasks
方法告诉 Rails 加载它们
class MyGem::Railtie < Rails::Railtie
rake_tasks do
load "path/to/my_gem.tasks"
end
end
默认情况下,Rails 会从你的加载路径加载生成器。但是,如果你希望将生成器放在不同的位置,你可以在你的 railtie 中指定一个块,该块将在正常生成器查找期间加载它们
class MyGem::Railtie < Rails::Railtie
generators do
require "path/to/my_gem_generator"
end
end
由于加载路径上的文件名在不同 gem 之间是共享的,因此请确保通过 railtie 加载的文件具有唯一的名称。
在 Rails 服务器启动时运行另一个程序
在开发过程中,通常需要在 Rails Server
旁边运行另一个进程。例如,你可能希望启动 Webpack 或 React 服务器。或者,你可能需要运行你的作业调度程序进程,例如 Sidekiq。这通常是通过打开一个新的 shell 并从此处运行程序来完成的。
Rails 允许你指定一个 server
块,该块将在 Rails 服务器启动时调用。这样,你的用户就不需要记住打开一个新的 shell 并运行另一个程序,从而使每个人都更容易理解。它可以像这样使用
class MyGem::Railtie < Rails::Railtie
server do
WebpackServer.start
end
end
Application
和 Engine
引擎只不过是一个已经设置了一些初始化器的 railtie。由于 Rails::Application
是一个引擎,因此这里描述的相同配置可以用于两者。
请务必查看这些特定类的文档以获取更多信息。
- A
- C
- G
- I
- R
- S
常量
ABSTRACT_RAILTIES | = | %w(Rails::Railtie Rails::Engine Rails::Application) |
属性
[R] | load_index |
类公共方法
abstract_railtie?() 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 172 def abstract_railtie? ABSTRACT_RAILTIES.include?(name) end
configure(&block) 链接
允许你配置 railtie。这与 Railtie::Configurable
中看到的相同方法,但此模块不再是 Railtie
的所有子类的必需项,因此我们在这里提供类方法。
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 190 def configure(&block) instance.configure(&block) end
console(&blk) 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 156 def console(&blk) register_block_for(:load_console, &blk) end
generators(&blk) 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 164 def generators(&blk) register_block_for(:generators, &blk) end
inherited(subclass) 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 198 def inherited(subclass) subclass.increment_load_index super end
instance() 链接
由于 Rails::Railtie
不能实例化,因此任何调用 instance
的方法都只打算在 Railtie
的子类上调用。
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 183 def instance @instance ||= new end
railtie_name(name = nil) 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 176 def railtie_name(name = nil) @railtie_name = name.to_s if name @railtie_name ||= generate_railtie_name(self.name) end
rake_tasks(&blk) 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 152 def rake_tasks(&blk) register_block_for(:rake_tasks, &blk) end
runner(&blk) 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 160 def runner(&blk) register_block_for(:runner, &blk) end
server(&blk) 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 168 def server(&blk) register_block_for(:server, &blk) end
subclasses() 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 148 def subclasses super.reject(&:abstract_railtie?).sort end
类保护方法
increment_load_index() 链接
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 206 def increment_load_index @@load_counter ||= 0 @load_index = (@@load_counter += 1) end
实例公共方法
config() 链接
这用于在 Railtie 上创建 config
对象,它是 Railtie::Configuration
的一个实例,由 Railtie 和 Application
用于存储相关配置。
来源:显示 | 在 GitHub 上
# File railties/lib/rails/railtie.rb, line 262 def config @config ||= Railtie::Configuration.new end