Spec-Zone.ru › Ruby on Rails 8.1

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

Подключённые модули:
Rails::Generators::Actions

Открытые методы класса

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 с учётом текущего пространства имён класса.

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

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

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_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.

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.

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, расположенного на один уровень выше корневого каталога исходников; если это не удаётся, использует описание по умолчанию.

Вызывает метод суперкласса
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» в качестве имени генератора.

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

Вызывает генератор на основе значения, переданного пользователем для опции с заданным именем «name». При вызове этого метода создаётся опция класса, которую можно настроить с помощью хеша.

Примеры

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, за исключением того, что Generator в конце имени класса удаляется.

Вызывает метод суперкласса
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 в качестве значения по умолчанию.

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