класс Rails::Railtie
Railtie — это ядро фреймворка Rails и предоставляет несколько крючков для расширения Rails и/или изменения процесса инициализации.
Каждый главный компонент Rails (Action Mailer, Action Controller, Action View и Active Record) является Railtie. Каждый из них отвечает за свою собственную инициализацию. Это делает сам Rails свободным от каких-либо крючков компонентов, позволяя использовать другие компоненты вместо стандартных значений Rails.
Разработка расширения Rails не требует реализации Railtie, но если вам нужно взаимодействовать с фреймворком Rails во время или после запуска, тогда Railtie необходим.
Например, расширение, выполняющее любое из следующего, потребует Railtie:
-
создание инициализаторов
-
настройка фреймворка Rails для приложения, например, установка генератора
-
добавление ключей
config.*в среду -
настройка подписчика с помощью ActiveSupport::Notifications
-
добавление задач rake
Создание вашего Railtie
Чтобы расширить Rails с помощью Railtie, создайте класс Railtie, который наследуется от Rails::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 в процесс запуска Rails, вам просто нужно создать блок инициализатора:
class MyRailtie < Rails::Railtie
initializer "my_railtie.configure_rails_initialization" do
# some initialization behavior
end
end
Если указан, блок также может принимать объект приложения, в случае если вам нужно получить доступ к некоторым конфигурациям приложения, таким как middleware:
class MyRailtie < Rails::Railtie
initializer "my_railtie.configure_rails_initialization" do |app|
app.middleware.use MyRailtie::Middleware
end
end
Наконец, вы также можете передать :before и :after в качестве опции инициализатору, если вы хотите связать его с определенным этапом процесса инициализации.
Конфигурация
Внутри класса Railtie вы можете получить доступ к объекту конфигурации, который содержит конфигурацию, общую для всех railtie и приложения:
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 и генераторов
Если ваш railtie имеет задачи rake, вы можете указать Rails загрузить их с помощью метода ::rake_tasks:
class MyRailtie < Rails::Railtie
rake_tasks do
load "path/to/my_railtie.tasks"
end
end
По умолчанию Rails загружает генераторы из вашего пути загрузки. Однако, если вы хотите разместить свои генераторы в другом месте, вы можете указать в вашем Railtie блок, который загрузит их во время обычного поиска генераторов:
class MyRailtie < Rails::Railtie
generators do
require "path/to/my_railtie_generator"
end
end
Приложение и Двигатель
Rails::Engine — это просто Railtie с уже настроенными инициализаторами. И поскольку Rails::Application является движком, описанную здесь конфигурацию можно использовать в обоих случаях.
Убедитесь, что вы ознакомились с документацией этих конкретных классов для получения дополнительной информации.
Константы
- ABSTRACT_RAILTIES
Публичные методы класса
# File railties/lib/rails/railtie.rb, line 159 def abstract_railtie? ABSTRACT_RAILTIES.include?(name) end
Позволяет настроить railtie. Это тот же метод, что и в Railtie::Configurable, но этот модуль больше не требуется для всех подклассов Railtie, поэтому мы предоставляем метод класса здесь.
# File railties/lib/rails/railtie.rb, line 181 def configure(&block) instance.configure(&block) end
# File railties/lib/rails/railtie.rb, line 141 def console(&blk) @load_console ||= [] @load_console << blk if blk @load_console end
# File railties/lib/rails/railtie.rb, line 153 def generators(&blk) @generators ||= [] @generators << blk if blk @generators end
# File railties/lib/rails/railtie.rb, line 129
def inherited(base)
unless base.abstract_railtie?
subclasses << base
end
end Поскольку Rails::Railtie не может быть экземпляризирован, любые методы, которые вызывают instance, предназначены для вызова только на подклассах Railtie.
# File railties/lib/rails/railtie.rb, line 170 def instance @instance ||= new end
# File railties/lib/rails/railtie.rb, line 203
def initialize
if self.class.abstract_railtie?
raise "#{self.class.name} is abstract, you cannot instantiate it directly."
end
end # File railties/lib/rails/railtie.rb, line 163 def railtie_name(name = nil) @railtie_name = name.to_s if name @railtie_name ||= generate_railtie_name(self.name) end
# File railties/lib/rails/railtie.rb, line 135 def rake_tasks(&blk) @rake_tasks ||= [] @rake_tasks << blk if blk @rake_tasks end
# File railties/lib/rails/railtie.rb, line 174 def respond_to_missing?(*args) instance.respond_to?(*args) || super end
# File railties/lib/rails/railtie.rb, line 147 def runner(&blk) @load_runner ||= [] @load_runner << blk if blk @load_runner end
# File railties/lib/rails/railtie.rb, line 125 def subclasses @subclasses ||= [] end
Защищенные методы класса
# File railties/lib/rails/railtie.rb, line 186
def generate_railtie_name(class_or_module)
ActiveSupport::Inflector.underscore(class_or_module).tr("/", "_")
end Если метод класса отсутствует, то отправьте вызов метода экземпляру Railtie.
# File railties/lib/rails/railtie.rb, line 192
def method_missing(name, *args, &block)
if instance.respond_to?(name)
instance.public_send(name, *args, &block)
else
super
end
end Публичные методы экземпляра
# File railties/lib/rails/railtie.rb, line 213 def config @config ||= Railtie::Configuration.new end
# File railties/lib/rails/railtie.rb, line 209 def configure(&block) instance_eval(&block) end
# File railties/lib/rails/railtie.rb, line 217
def railtie_namespace
@railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:railtie_namespace) }
end
© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.