跳至內容 跳至搜尋
方法
A
B
D
E
G
H
I
M
N
R
S
U
W
已包含模組

類別公開方法

add_shebang_option!()

小型巨集,用於將 ruby 作為具有適當預設值的選項添加到產生器,以及一個稱為 shebang 的實例輔助方法。

# 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

banner()

使用 Rails 預設橫幅。

# 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

base_name()

設定 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_root()

傳回一組常用產生器的根目錄。這用於動態猜測預設的程式碼根目錄。

# File railties/lib/rails/generators/base.rb, line 236
def self.base_root
  __dir__
end

default_aliases_for_option(name, options)

在 Rails::Generators.aliases 中查詢給定選項名稱的預設別名並傳回。

# 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

default_for_option(config, name, options, default)

在 config 中查詢給定選項名稱的預設值並傳回。

# 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

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()

傳回給定產生器的預設程式碼根目錄。Rails 內部使用它來設定其產生器的程式碼根目錄。如果您想自訂程式碼根目錄,您應該使用 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

default_value_for_option(name, options)

在 Rails::Generators.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

desc(description = nil)

嘗試從程式碼根目錄上一層資料夾中的 USAGE 檔案中取得描述,否則使用預設描述。

# 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

generator_name()

移除命名空間並取得產生器名稱。例如,Rails::Generators::ModelGenerator 將傳回 "model" 作為產生器名稱。

# 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

hide!()

便捷方法,用於在執行 rails generator 命令時從可用的產生器中隱藏此產生器。

# File railties/lib/rails/generators/base.rb, line 61
def self.hide!
  Rails::Generators.hide_namespace(namespace)
end

hook_for(*names, &block)

根據使用者提供給名為「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`。

假設您正在建立一個需要從測試單元叫用控制器產生器的產生器。您的第一次嘗試是

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
# 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

namespace(name = nil)

便捷方法,用於從類別名稱中取得命名空間。它與 Thor 預設值相同,只是類別結尾的 Generator 被移除。

# 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

remove_hook_for(*names)

移除先前新增的鉤子。

remove_hook_for :orm
# 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

source_root(path = nil)

使用 `default_source_root` 作為預設值,傳回此產生器的程式碼根目錄。

# 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

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