класс Rails::Generators::Base
Публичные методы класса
# File railties/lib/rails/generators/base.rb, line 217 def self.base_root File.dirname(__FILE__) end
Возвращает базовый корень для общего набора генераторов. Используется для динамического определения корня исходных файлов по умолчанию.
# File railties/lib/rails/generators/base.rb, line 208 def self.default_source_root return unless base_name && generator_name return unless default_generator_root path = File.join(default_generator_root, 'templates') path if File.exist?(path) end
Возвращает корень исходных файлов по умолчанию для данного генератора. Внутренне используется Rails для установки корня исходных файлов генераторов. Если требуется настроить корень исходных файлов, используйте метод source_root.
# File railties/lib/rails/generators/base.rb, line 30
def self.desc(description=nil)
return super if description
@desc ||= if usage_path
ERB.new(File.read(usage_path)).result(binding)
else
"Description:\n Create #{base_name.humanize.downcase} files for #{generator_name} generator."
end
end Попытка получить описание из файла USAGE на один уровень выше корня исходных файлов, в противном случае используется описание по умолчанию.
# File railties/lib/rails/generators/base.rb, line 50 def self.hide! Rails::Generators.hide_namespace self.namespace end
Удобный метод для скрытия этого генератора из доступных при выполнении команды rails generator.
# File railties/lib/rails/generators/base.rb, line 163
def self.hook_for(*names, &block)
options = names.extract_options!
in_base = options.delete(:in) || base_name
as_hook = options.delete(:as) || generator_name
names.each do |name|
unless class_options.key?(name)
defaults = if options[:type] == :boolean
{ }
elsif [true, false].include?(default_value_for_option(name, options))
{ banner: "" }
else
{ desc: "#{name.to_s.humanize} to be invoked", banner: "NAME" }
end
class_option(name, defaults.merge!(options))
end
hooks[name] = [ in_base, as_hook ]
invoke_from_option(name, options, &block)
end
end Вызывает генератор на основе значения, предоставленного пользователем для заданного параметра «имя». При вызове этого метода создается параметр класса, и вы можете задать хэш для его настройки.
Примеры
module Rails::Generators
class ControllerGenerator < Base
hook_for :test_framework, aliases: "-t"
end
end
В приведенном выше примере будет создан параметр тестового фреймворка, и будет вызван генератор на основе значения, предоставленного пользователем.
Например, если пользователь вызывает генератор контроллеров так:
rails generate controller Account --test-framework=test_unit
Генератор контроллеров затем попытается вызвать следующие генераторы:
"rails:test_unit", "test_unit:controller", "test_unit"
Обратите внимание, что «rails:generators:test_unit» также может быть загружен, то, что Rails ищет, это первая и последняя части пространства имён. Именно это позволяет любому тестовому фреймворку подключиться к Rails, если он предоставляет какие-либо из указанных выше хуков.
Параметры
Первая и последняя части, используемые для поиска вызываемого генератора, угадываются на основе вызовов класса ::hook_for, как показано в примере выше. Это можно настроить с помощью двух параметров: :in и :as.
Предположим, вы создаёте генератор, которому необходимо вызвать генератор контроллеров из test unit. Ваша первая попытка:
class AwesomeGenerator < Rails::Generators::Base hook_for :test_framework end
Поиск в этом случае для test_unit в качестве ввода:
"test_unit:awesome", "test_unit"
Что не является желаемым поиском. Вы можете изменить его, предоставив параметр :as:
class AwesomeGenerator < Rails::Generators::Base hook_for :test_framework, as: :controller end
И теперь он будет искать в:
"test_unit:controller", "test_unit"
Аналогично, если вы хотите, чтобы он также искал в пространстве имён rails, вам просто нужно предоставить значение :in:
class AwesomeGenerator < Rails::Generators::Base hook_for :test_framework, in: :rails, as: :controller end
И поиск точно такой же, как и прежде:
"rails:test_unit", "test_unit:controller", "test_unit"
Переключатели
Все хуки поставляются с переключателями для пользовательского интерфейса. Если вы не хотите использовать какой-либо тестовый фреймворк, вы можете сделать следующее:
rails generate controller Account --skip-test-framework
Или аналогично:
rails generate controller Account --no-test-framework
Булевы хуки
В некоторых случаях вам может потребоваться предоставить булевый хук. Например, разработчики webrat могут захотеть, чтобы webrat был доступен в генераторе контроллеров. Это можно сделать так:
Rails::Generators::ControllerGenerator.hook_for :webrat, type: :boolean
Затем, если вы хотите вызвать webrat, просто передайте:
rails generate controller Account --webrat
Поиск хуков аналогичен вышеприведённому:
"rails:generators:webrat", "webrat:generators:controller", "webrat"
Настраиваемые вызовы
Вы также можете предоставить блок ::hook_for для настройки того, как будет вызываться хук. Блок получает два аргумента, экземпляр текущего класса и класс, который будет вызван.
Например, в генераторе ресурсов контроллер должен вызываться с множественным именем класса. Но по умолчанию он вызывается с тем же именем, что и генератор ресурсов, который является единственным. Чтобы изменить это, мы можем предоставить блок для настройки того, как вызывается контроллер.
hook_for :resource_controller do |instance, controller| instance.invoke controller, [ instance.name.pluralize ] end
# File railties/lib/rails/generators/base.rb, line 43 def self.namespace(name=nil) return super if name @namespace ||= super.sub(/_generator$/, '').sub(/:generators:/, ':') end
Удобный метод для получения пространства имён из имени класса. Он такой же, как и у Thor по умолчанию, за исключением того, что в конце класса удаляется генератор.
# File railties/lib/rails/generators/base.rb, line 189
def self.remove_hook_for(*names)
remove_invocation(*names)
names.each do |name|
hooks.delete(name)
end
end Удаляет ранее добавленный хук.
remove_hook_for :orm
# File railties/lib/rails/generators/base.rb, line 23 def self.source_root(path=nil) @_source_root = path if path @_source_root ||= default_source_root end
Возвращает корень исходных файлов для этого генератора, используя ::default_source_root по умолчанию.
Защищённые методы класса
# File railties/lib/rails/generators/base.rb, line 346
def self.add_shebang_option!
class_option :ruby, type: :string, aliases: "-r", default: Thor::Util.ruby_command,
desc: "Path to the Ruby binary of your choice", banner: "PATH"
no_tasks {
define_method :shebang do
@shebang ||= begin
command = if options[:ruby] == Thor::Util.ruby_command
"/usr/bin/env #{File.basename(Thor::Util.ruby_command)}"
else
options[:ruby]
end
"#!#{command}"
end
end
}
end Небольшой макрос для добавления ruby в качестве параметра генератора с соответствующим значением по умолчанию плюс вспомогательный метод экземпляра shebang.
# File railties/lib/rails/generators/base.rb, line 275
def self.banner
"rails generate #{namespace.sub(/^rails:/,'')} #{self.arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, ' ')
end Использование стандартного баннера Rails.
# File railties/lib/rails/generators/base.rb, line 280
def self.base_name
@base_name ||= begin
if base = name.to_s.split('::').first
base.underscore
end
end
end Устанавливает ::base_name, учитывая текущее пространство имён класса.
# File railties/lib/rails/generators/base.rb, line 307 def self.default_aliases_for_option(name, options) default_for_option(Rails::Generators.aliases, name, options, options[:aliases]) end
Возвращает стандартные псевдонимы для заданного имени параметра, выполняя поиск в Rails::Generators.aliases.
# File railties/lib/rails/generators/base.rb, line 312
def self.default_for_option(config, name, options, default)
if generator_name and c = config[generator_name.to_sym] and c.key?(name)
c[name]
elsif base_name and c = config[base_name.to_sym] and c.key?(name)
c[name]
elsif config[:rails].key?(name)
config[:rails][name]
else
default
end
end Возвращает значение по умолчанию для заданного имени параметра, выполняя поиск в config.
# File railties/lib/rails/generators/base.rb, line 372 def self.default_generator_root path = File.expand_path(File.join(base_name, generator_name), base_root) path if File.exist?(path) end
# File railties/lib/rails/generators/base.rb, line 301 def self.default_value_for_option(name, options) default_for_option(Rails::Generators.options, name, options, options[:default]) end
Возвращает значение по умолчанию для заданного имени параметра, выполняя поиск в Rails::Generators.options.
# File railties/lib/rails/generators/base.rb, line 290
def self.generator_name
@generator_name ||= begin
if generator = name.to_s.split('::').last
generator.sub!(/Generator$/, '')
generator.underscore
end
end
end Удаляет пространства имён и получает имя генератора. Например, Rails::Generators::ModelGenerator вернёт «model» в качестве имени генератора.
# File railties/lib/rails/generators/base.rb, line 364
def self.usage_path
paths = [
source_root && File.expand_path("../USAGE", source_root),
default_generator_root && File.join(default_generator_root, "USAGE")
]
paths.compact.detect { |path| File.exist? path }
end Защищённые методы экземпляра
# File railties/lib/rails/generators/base.rb, line 267
def extract_last_module(nesting)
nesting.inject(Object) do |last_module, nest|
break unless last_module.const_defined?(nest, false)
last_module.const_get(nest)
end
end Принимает массив вложенных модулей и извлекает последний модуль
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.