класс Rails::Generators::Base
Публичные методы класса
Возвращает базовый каталог для общего набора генераторов. Используется для динамического определения корневого каталога по умолчанию.
# File railties/lib/rails/generators/base.rb, line 217 def self.base_root File.dirname(__FILE__) end
Возвращает корневой каталог по умолчанию для данного генератора. Внутренне используется Rails для установки корневого каталога генераторов. Если вы хотите настроить корневой каталог, используйте source_root.
# 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
Пытается получить описание из файла USAGE на один каталог выше корневого каталога, в противном случае использует описание по умолчанию.
# 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 Удобный метод для скрытия этого генератора из доступных при выполнении команды rails generate.
# File railties/lib/rails/generators/base.rb, line 50 def self.hide! Rails::Generators.hide_namespace self.namespace end
Вызывает генератор на основе значения, введённого пользователем для данного параметра с именем «name». При вызове этого метода создаётся параметр класса, и вы можете установить хэш для его настройки.
Примеры
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, как видно в примере выше. Это можно настроить с помощью двух параметров: :base и :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, вам нужно только предоставить значение :base:
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 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 Удобный метод для получения пространства имён из имени класса. Он такой же, как Thor по умолчанию, за исключением того, что генератор в конце класса удаляется.
# 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
Удаляет ранее добавленный хук.
remove_hook_for :orm
# 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 Возвращает корневой каталог для этого генератора, используя ::default_source_root в качестве значения по умолчанию.
# 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
Защищённые методы класса
Небольшой макрос для добавления ruby в качестве параметра генератора с правильным значением по умолчанию, плюс вспомогательный метод экземпляра shebang.
# 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 Использовать баннер по умолчанию Rails.
# File railties/lib/rails/generators/base.rb, line 275
def self.banner
"rails generate #{namespace.sub(/^rails:/,'')} #{self.arguments.map{ |a| a.usage }.join(' ')} [options]".gsub(/\s+/, ' ')
end Устанавливает ::base_name, учитывая текущее пространство имён класса.
# 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 Возвращает значения по умолчанию для параметра с данным именем, выполнив поиск в Rails::Generators.aliases.
# 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
Возвращает значение по умолчанию для параметра с данным именем, выполнив поиск в config.
# 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 # 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
Возвращает значение по умолчанию для параметра с данным именем, выполнив поиск в Rails::Generators.options.
# 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::ModelGenerator вернёт «model» как имя генератора.
# 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 # 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–2016 David Heinemeier Hansson
Licensed under the MIT License.