Spec-Zone.ru › Ruby on Rails 7.1

класс Rails::Generators::Base

Родитель:
Thor::Group
Включенные модули:
Rails::Generators::Actions

Публичные методы класса

base_root() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 236
def self.base_root
  __dir__
end

Возвращает корневой каталог для набора генераторов. Используется для динамического определения корневого каталога по умолчанию.

default_source_root() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 227
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.

desc(description = nil) Показать исходный код
# 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 в папке над корневым каталогом источника, иначе использует описание по умолчанию.

Вызывается метод суперкласса
hide!() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 61
def self.hide!
  Rails::Generators.hide_namespace(namespace)
end

Удобный метод для скрытия этого генератора из доступных при выполнении команды rails generator.

hook_for(*names, &block) Показать исходный код
# 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

    klass = self

    singleton_class.define_method("#{name}_generator") do
      value = class_options[name].default
      Rails::Generators.find_by_namespace(klass.generator_name, value)
    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
namespace(name = nil) Показать исходный код
# 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, за исключением того, что генератор в конце класса удаляется.

Вызывается метод суперкласса
remove_hook_for(*names) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 207
def self.remove_hook_for(*names)
  remove_invocation(*names)

  names.each do |name|
    singleton_class.undef_method("#{name}_generator")
    hooks.delete(name)
  end
end

Удаляет ранее добавленный хук.

remove_hook_for :orm
source_root(path = nil) Показать исходный код
# 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 в качестве значения по умолчанию.

Методы закрытого класса

add_shebang_option!() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 396
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».

banner() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 329
def self.banner # :doc:
  "bin/rails generate #{namespace.delete_prefix("rails:")} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
end

Использование стандартного баннера Rails.

base_name() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 334
def self.base_name # :doc:
  @base_name ||= if base = name.to_s.split("::").first
    base.underscore
  end
end

Устанавливает base_name с учётом текущего пространства имён класса.

default_aliases_for_option(name, options) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 357
def self.default_aliases_for_option(name, options) # :doc:
  default_for_option(Rails::Generators.aliases, name, options, options[:aliases])
end

Возвращает алиасы по умолчанию для заданного имени опции, выполняя поиск в Rails::Generators.aliases.

default_for_option(config, name, options, default) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 362
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.

default_generator_root() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 422
def self.default_generator_root # :doc:
  path = File.expand_path(File.join(base_name, generator_name), base_root)
  path if File.exist?(path)
end
default_value_for_option(name, options) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 351
def self.default_value_for_option(name, options) # :doc:
  default_for_option(Rails::Generators.options, name, options, options[:default])
end

Возвращает значение по умолчанию для заданного имени опции, выполняя поиск в Rails::Generators.options.

generator_name() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 342
def self.generator_name # :doc:
  @generator_name ||= if generator = name.to_s.split("::").last
    generator.delete_suffix!("Generator")
    generator.underscore
  end
end

Удаляет пространства имён и получает имя генератора. Например, Rails::Generators::ModelGenerator вернёт «model» в качестве имени генератора.

usage_path() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 414
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

Методы закрытого экземпляра

extract_last_module(nesting) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 287
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

Принимает массив вложенных модулей и извлекает последний модуль.

indent(content, multiplier = 2) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 302
def indent(content, multiplier = 2) # :doc:
  spaces = " " * multiplier
  content.each_line.map { |line| line.blank? ? line : "#{spaces}#{line}" }.join
end
module_namespacing(&block) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 296
def module_namespacing(&block) # :doc:
  content = capture(&block)
  content = wrap_with_namespace(content) if namespaced?
  concat(content)
end

Оборачивает блок в пространство имён текущего приложения, если оно существует и не пропущено.

namespace() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 312
def namespace # :doc:
  Rails::Generators.namespace
end
namespaced?() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 316
def namespaced? # :doc:
  !options[:skip_namespace] && namespace
end
namespaced_path() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 324
def namespaced_path # :doc:
  @namespaced_path ||= namespace_dirs.join("/")
end
wrap_with_namespace(content) Показать исходный код
# File railties/lib/rails/generators/base.rb, line 307
def wrap_with_namespace(content) # :doc:
  content = indent(content).chomp
  "module #{namespace.name}\n#{content}\nend\n"
end

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API