Rails 生成器查找策略在覆盖生成器内置的 Rails 时不起作用

问题描述 投票:0回答:1

我正在尝试覆盖轨道控制器生成器。在我的 Rails 应用程序中,我在 lib/generators/controller_generator.rb 位置创建了文件。

  class ControllerGenerator < Rails::Generators::NamedBase
    def hello
      puts "hello"
    end
  end

当我从终端运行命令

rails g controller test --pretend
时,我希望打印
hello
消息,但不是调用内置控制器的实际 Rails,而是创建以下文件。

  create  app/controllers/test_controller.rb
  invoke  erb
  create    app/views/test
  invoke  helper
  create    app/helpers/test_helper.rb
  invoke    test_unit

按照 Rails 指南查找路径文档,预计不会有关于输出 https://guides.rubyonrails.org/generators.html#generator-resolution 。根据下面的文档,在我的情况下,rails 将遵循查找路径。

rails/generators/controller/controller_generator.rb
generators/controller/controller_generator.rb
rails/generators/controller_generator.rb
generators/controller_generator.rb

我的文件存在于 lib/generators/controller_generator.rb 位置,该位置与查找路径生成器/controller_generator.rb 匹配。

我的问题是为什么执行内置控制器生成器而不是我自己的控制器生成器?

ruby-on-rails rails-generators
1个回答
0
投票

文档的优先顺序似乎是正确的

rails/generators/controller/controller_generator.rb
generators/controller/controller_generator.rb
rails/generators/controller_generator.rb
generators/controller_generator.rb

您的问题是,现在您的控制器排在第四位 (

generators/controller_generator.rb
),而 Rails 排在第三位 (
rails/generators/controller_generator.rb
)。

这也是为什么正如您所指出的,使用

lib/rails/generators/controller/controller_generator.rb
lib/generators/controller/controller_generator.rb
确实有效,因为您跳到了轨道生成器前面。

TL;博士

基于一些试验和错误,名为生成器的内置轨道似乎将优先于“lib/generators”中的生成器。

含义:

  • “lib/generators/controller_generator.rb”不会作为生成器加载;但是
  • “lib/generators/example_generator.rb”将

如果将相同的控制器生成器放在“lib/rails/generators/controller/controller_generator.rb”中,该类将加载,“lib/controller/controller_generator.rb”也将加载

这似乎与

Rails::Generators
命名空间查找的工作方式有关。例如:

具有以下目录结构:

  • “lib/generators/controller_generator.rb”
  • “lib/generators/example_generator.rb”

相关的命名空间是:

{
    ["rails:controller", Rails::Generators::ControllerGenerator]
    ["example", ExampleGenerator]
}

但是如果我们将其更改为:

  • “lib/rails/rails/generators/controller/controller_generator.rb”
  • “lib/generators/example_generator.rb”

相关命名空间变为:

{
    ["rails:controller", Rails::Generators::ControllerGenerator]
    ["controller", ControllerGenerator]
    ["example", ExampleGenerator]
}

源代码指出(为了清楚地阐明所提出的问题而进行了更改:

将搜索以下命令:

“控制器”,“rails:控制器”

这似乎是由于

lookup
进程将在找到第一个有效路径(Source)后返回并且“rails/generators”在
lookup_paths
中给出先例而引起的:

def lookup_paths # :doc:
  @lookup_paths ||= %w( rails/generators generators )
end
© www.soinside.com 2019 - 2024. All rights reserved.