класс Rails::Generators::Base
Открытые методы класса
# File railties/lib/rails/generators/base.rb, line 228 def self.base_root __dir__ end
Возвращает базовый корень для общего набора генераторов. Используется для динамического определения корня исходного кода по умолчанию.
# File railties/lib/rails/generators/base.rb, line 219 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 41
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 61 def self.hide! Rails::Generators.hide_namespace(namespace) end
Удобный метод для скрытия этого генератора из доступных при выполнении команды rails generator.
# File railties/lib/rails/generators/base.rb, line 174
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
В приведенном примере будет создан параметр фреймворка тестирования, и будет вызван генератор на основе значения, предоставленного пользователем.
Например, если пользователь вызовет генератор контроллера как:
bin/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"
Переключатели
Все хуки поставляются с переключателями для пользовательского интерфейса. Если вы не хотите использовать какой-либо фреймворк тестирования, вы можете сделать:
bin/rails generate controller Account --skip-test-framework
Или аналогично:
bin/rails generate controller Account --no-test-framework
Булевы хуки
В некоторых случаях вам может потребоваться предоставить булевый хук. Например, разработчики webrat могут захотеть сделать webrat доступным для генератора контроллеров. Это можно достичь так:
Rails::Generators::ControllerGenerator.hook_for :webrat, type: :boolean
Затем, если вы хотите вызвать webrat, просто предоставьте:
bin/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 54
def self.namespace(name = nil)
return super if name
@namespace ||= super.delete_suffix("_generator").sub(/:generators:/, ":")
end Удобный метод для получения пространства имен из имени класса. Он такой же, как по умолчанию в Thor, за исключением того, что генератор в конце класса удаляется.
# File railties/lib/rails/generators/base.rb, line 200
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 34 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 392
def self.add_shebang_option! # :doc:
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 321
def self.banner # :doc:
"rails generate #{namespace.delete_prefix("rails:")} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
end Использует значение Rails по умолчанию для баннера.
# File railties/lib/rails/generators/base.rb, line 326
def self.base_name # :doc:
@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 353 def self.default_aliases_for_option(name, options) # :doc: default_for_option(Rails::Generators.aliases, name, options, options[:aliases]) end
Возвращает значения алиасов по умолчанию для данного имени параметра, выполняя поиск в Rails::Generators.aliases.
# File railties/lib/rails/generators/base.rb, line 358
def self.default_for_option(config, name, options, default) # :doc:
if generator_name && (c = config[generator_name.to_sym]) && c.key?(name)
c[name]
elsif base_name && (c = config[base_name.to_sym]) && c.key?(name)
c[name]
elsif config[:rails].key?(name)
config[:rails][name]
else
default
end
end Возвращает значение по умолчанию для данного имени параметра, выполняя поиск в конфигурации.
# File railties/lib/rails/generators/base.rb, line 418 def self.default_generator_root # :doc: 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 347 def self.default_value_for_option(name, options) # :doc: default_for_option(Rails::Generators.options, name, options, options[:default]) end
Возвращает значение по умолчанию для данного имени параметра, выполняя поиск в Rails::Generators.options.
# File railties/lib/rails/generators/base.rb, line 336
def self.generator_name # :doc:
@generator_name ||= begin
if generator = name.to_s.split("::").last
generator.delete_suffix!("Generator")
generator.underscore
end
end
end Удаляет пространства имен и получает имя генератора. Например, Rails::Generators::ModelGenerator вернёт «model» в качестве имени генератора.
# File railties/lib/rails/generators/base.rb, line 410
def self.usage_path # :doc:
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 279
def extract_last_module(nesting) # :doc:
nesting.inject(Object) do |last_module, nest|
break unless last_module.const_defined?(nest, false)
last_module.const_get(nest)
end
end Принимает массив вложенных модулей и извлекает последний модуль
# File railties/lib/rails/generators/base.rb, line 294
def indent(content, multiplier = 2) # :doc:
spaces = " " * multiplier
content.each_line.map { |line| line.blank? ? line : "#{spaces}#{line}" }.join
end # File railties/lib/rails/generators/base.rb, line 288 def module_namespacing(&block) # :doc: content = capture(&block) content = wrap_with_namespace(content) if namespaced? concat(content) end
Оборачивает блок с именным пространством текущего приложения, если пространство имён существует и не пропущено
# File railties/lib/rails/generators/base.rb, line 304 def namespace # :doc: Rails::Generators.namespace end
# File railties/lib/rails/generators/base.rb, line 308 def namespaced? # :doc: !options[:skip_namespace] && namespace end
# File railties/lib/rails/generators/base.rb, line 316
def namespaced_path # :doc:
@namespaced_path ||= namespace_dirs.join("/")
end # File railties/lib/rails/generators/base.rb, line 299
def wrap_with_namespace(content) # :doc:
content = indent(content).chomp
"module #{namespace.name}\n#{content}\nend\n"
end
© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.