класс Rails::Generators::Base
Публичные методы класса
# File railties/lib/rails/generators/base.rb, line 222 def self.base_root __dir__ end
Возвращает базовый корень для общего набора генераторов. Используется для динамической оценки корня исходных файлов по умолчанию.
# File railties/lib/rails/generators/base.rb, line 213 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 35
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 55 def self.hide! Rails::Generators.hide_namespace(namespace) end
Удобный метод для скрытия данного генератора из доступных при запуске команды rails generator.
# File railties/lib/rails/generators/base.rb, line 168
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 48 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 194
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 28 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 385
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 314
def self.banner # :doc:
"rails generate #{namespace.sub(/^rails:/, '')} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
end Использует баннер по умолчанию Rails.
# File railties/lib/rails/generators/base.rb, line 319
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 346 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 351
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 Возвращает значение по умолчанию для имени параметра, выполняя поиск в config.
# File railties/lib/rails/generators/base.rb, line 411 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 340 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 329
def self.generator_name # :doc:
@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 403
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 272
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 287
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 281 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 297 def namespace # :doc: Rails::Generators.namespace end
# File railties/lib/rails/generators/base.rb, line 301 def namespaced? # :doc: !options[:skip_namespace] && namespace end
# File railties/lib/rails/generators/base.rb, line 309
def namespaced_path # :doc:
@namespaced_path ||= namespace_dirs.join("/")
end # File railties/lib/rails/generators/base.rb, line 292
def wrap_with_namespace(content) # :doc:
content = indent(content).chomp
"module #{namespace.name}\n#{content}\nend\n"
end
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.