Spec-Zone.ru › Ruby on Rails 6.0

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

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

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

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

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

default_source_root() Показать исходный код
# 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.

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

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

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

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

Вызывает генератор на основе значения, предоставленного пользователем для опции с именем «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, как показано в примере выше. Это можно настроить с помощью двух опций: :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
namespace(name = nil) Показать исходный код
# 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 по умолчанию, за исключением того, что генератор в конце класса удаляется.

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

Приватные методы класса

add_shebang_option!() Показать исходный код
# 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.

banner() Показать исходный код
# 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.

base_name() Показать исходный код
# 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, учитывая текущее пространство имён класса.

default_aliases_for_option(name, options) Показать исходный код
# 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.

default_for_option(config, name, options, default) Показать исходный код
# 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.

default_generator_root() Показать исходный код
# 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
default_value_for_option(name, options) Показать исходный код
# 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.

generator_name() Показать исходный код
# 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» в качестве имени генератора.

usage_path() Показать исходный код
# 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
END_OF_DOCUMENT_MARKER

Приватные методы экземпляра

extract_last_module(nesting) Показать исходный код
# 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

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

indent(content, multiplier = 2) Показать исходный код
# 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
module_namespacing(&block) Показать исходный код
# 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

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

namespace() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 297
def namespace # :doc:
  Rails::Generators.namespace
end
namespaced?() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 301
def namespaced? # :doc:
  !options[:skip_namespace] && namespace
end
namespaced_path() Показать исходный код
# File railties/lib/rails/generators/base.rb, line 309
def namespaced_path # :doc:
  @namespaced_path ||= namespace_dirs.join("/")
end
wrap_with_namespace(content) Показать исходный код
# 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–2019 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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