跳至內容 跳至搜尋

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 搭配或不搭配使用的擴充套件。

# 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 MyRailtie < Rails::Railtie
  initializer "my_railtie.configure_rails_initialization" do
    # some initialization behavior
  end
end

如果已指定,區塊也可以接收應用程式物件,以防你需要存取某些特定於應用程式的組態,例如中介軟體

class MyRailtie < Rails::Railtie
  initializer "my_railtie.configure_rails_initialization" do |app|
    app.middleware.use MyRailtie::Middleware
  end
end

最後,你也可以將 :before:after 傳遞為 initializer 的選項,以防你想要將它與初始化程序中的特定步驟結合使用。

組態

Railties 可以存取包含所有 railties 和應用程式共用組態的 config 物件

class MyRailtie < Rails::Railtie
  # Customize the ORM
  config.app_generators.orm :my_railtie_orm

  # Add a to_prepare block which is executed once in production
  # and before each request in development.
  config.to_prepare do
    MyRailtie.setup!
  end
end

載入 Rake 工作和 Generators

如果你的 railtie 有 Rake 工作,你可以透過方法 rake_tasks 告訴 Rails 載入它們

class MyRailtie < Rails::Railtie
  rake_tasks do
    load "path/to/my_railtie.tasks"
  end
end

預設情況下,Rails 會從你的載入路徑載入 generators。不過,如果你想要將 generators 放在不同的位置,你可以在你的 railtie 中指定一個區塊,它會在正常的 generators 查詢期間載入它們

class MyRailtie < Rails::Railtie
  generators do
    require "path/to/my_railtie_generator"
  end
end

由於載入路徑上的檔案名稱在各個 gem 中共用,請務必確定透過 railtie 載入的檔案具有唯一名稱。

在 Rails 伺服器啟動時執行另一個程式

在開發階段,通常必須在 Rails Server 旁邊執行另一個程序。例如,你可能想要啟動 Webpack 或 React 伺服器。或者,你可能需要執行你的工作排程程序,例如 Sidekiq。這通常是透過開啟新的 shell 並從這裡執行程式來完成的。

Rails 允許你指定一個 server 區塊,它會在 Rails 伺服器啟動時被呼叫。這樣,你的使用者就不必記得必須開啟新的 shell 並執行另一個程式,讓這對每個人來說都更不令人困惑。它可以像這樣使用

class MyRailtie < Rails::Railtie
  server do
    WebpackServer.start
  end
end

ApplicationEngine

引擎只不過是一個已經設定了一些初始化項目的 railtie。由於 Rails::Application 是引擎,因此這裡所述的相同組態可以用於兩者。

務必查看那些特定類別的文件以取得更多資訊。

命名空間
方法
A
C
G
I
R
S
包含的模組

常數

ABSTRACT_RAILTIES = %w(Rails::Railtie Rails::Engine Rails::Application)
 

屬性

[R] load_index

類別公開方法

abstract_railtie?()

# File railties/lib/rails/railtie.rb, line 172
def abstract_railtie?
  ABSTRACT_RAILTIES.include?(name)
end

configure(&block)

允許您設定 railtie。這是 Railtie::Configurable 中看到的方法,但這個模組不再是 Railtie 所有子類別的必要條件,因此我們在此提供類別方法。

# File railties/lib/rails/railtie.rb, line 190
def configure(&block)
  instance.configure(&block)
end

console(&blk)

# File railties/lib/rails/railtie.rb, line 156
def console(&blk)
  register_block_for(:load_console, &blk)
end

generators(&blk)

# File railties/lib/rails/railtie.rb, line 164
def generators(&blk)
  register_block_for(:generators, &blk)
end

inherited(subclass)

# File railties/lib/rails/railtie.rb, line 198
def inherited(subclass)
  subclass.increment_load_index
  super
end

instance()

由於 Rails::Railtie 無法實例化,因此任何呼叫 instance 的方法都只打算在 Railtie 的子類別上呼叫。

# File railties/lib/rails/railtie.rb, line 183
def instance
  @instance ||= new
end

railtie_name(name = nil)

# 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)

# File railties/lib/rails/railtie.rb, line 152
def rake_tasks(&blk)
  register_block_for(:rake_tasks, &blk)
end

runner(&blk)

# File railties/lib/rails/railtie.rb, line 160
def runner(&blk)
  register_block_for(:runner, &blk)
end

server(&blk)

# File railties/lib/rails/railtie.rb, line 168
def server(&blk)
  register_block_for(:server, &blk)
end

subclasses()

# File railties/lib/rails/railtie.rb, line 148
def subclasses
  super.reject(&:abstract_railtie?).sort
end

類別受保護方法

increment_load_index()

# File railties/lib/rails/railtie.rb, line 206
def increment_load_index
  @@load_counter ||= 0
  @load_index = (@@load_counter += 1)
end

執行個體公開方法

config()

這用於在 Railties 上建立 config 物件,也就是 Railtie::Configuration 的執行個體,這會由 Railties 和 Application 用來儲存相關設定。

# File railties/lib/rails/railtie.rb, line 263
def config
  @config ||= Railtie::Configuration.new
end