【问题标题】:How to change source for a custom rails generator? (Thor)如何更改自定义 Rails 生成器的源? (雷神)
【发布时间】:2012-04-10 09:57:32
【问题描述】:

我正在制作一个自定义生成器来生成一个新的 rails 应用程序,我就是这样做的

require 'thor'
require 'rails/generators/rails/app/app_generator'

class AppBuilder < Rails::AppBuilder
  include Thor::Actions
  include Thor::Shell
  ...
end

问题是,如何添加新的源目录(然后由Thor::Actions#copy_fileThor::Actions#template 和其他人使用)?我在 Thor 的文档中看到 Thor::Actions#source_paths 包含源(它是一个路径数组),所以我尝试在我的类中覆盖它(因为我已经包含了 Thor::Actions):

def source_paths
  [File.join(File.expand_path(File.dirname(__FILE__)), "templates")] + super
end

有了这个,我想在源代码中添加./templates 目录,同时仍然保留Rails 的目录(这就是+ super 在末尾的原因)。但它不起作用,它仍然将 Rails 的源路径列为唯一路径。

我尝试浏览 Rails 的源代码,但找不到 Rails 如何将 他的 目录放在源路径中。我真的很想知道:)

【问题讨论】:

    标签: ruby-on-rails generator thor


    【解决方案1】:

    这是一个旧帖子,但是,问题仍然存在,我花了一些时间来解决这个问题。如果有帮助,我在这里发表评论。

    Rails 默认添加路径 lib/templates,因此您可以通过在此目录中复制模板来自定义任何模板。

    检查正确的目录结构https://github.com/rails/rails/tree/v6.0.1/railties/lib/rails/generators/rails

    虽然有些微妙,但并不那么明显。

    helper生成器为例,在Rails官方文档中提到,结构是

    https://github.com/rails/rails/tree/v6.0.1/railties/lib/rails/generators/rails/helper

    - helper
      - templates
        - helper.rb.tt
      - helper_generator.rb 
    

    在这里,Railties 期望在您的项目中找到什么:

    - lib
      - templates 
        - helper
          - helper.rb
    

    您的helper.rbhelper.rb.tt 的副本

    最后一件事,如果你打算在Rails::Engine 中使用它,你必须告诉它加载那个路径

    # lib/blorgh/engine.rb 
    module Blorgh
      class Engine < ::Rails::Engine
        isolate_namespace Blorgh
        config.generators.templates << File.expand_path('../templates', __dir__)
      end
    end
    

    真的希望可以帮助他人并节省时间。

    1. https://github.com/rails/rails/blob/v6.0.1/railties/lib/rails/application/configuration.rb#L188
    2. https://guides.rubyonrails.org/generators.html#customizing-your-workflow-by-changing-generators-templates
    3. https://github.com/rails/rails/blob/v6.0.1/railties/CHANGELOG.md
    4. https://guides.rubyonrails.org/engines.html

    【讨论】:

      【解决方案2】:

      source_paths 方法在使用 AppBuilder 时不起作用。 (这是使用 rails 模板的另一种选择)。我在这个类所在的 app_builder.rb 文件旁边有一个 files 目录。我有这个工作,虽然看起来应该还有一个更优雅的方式。

      tree .
      |-- app_builder.rb
      |-- files
           `-- Gemfile
      
      class AppBuilder < Rails::AppBuilder
      
        def initialize generator
          super generator
          path = File.expand_path( File.join( '..', File.dirname( __FILE__ )) )
          source_paths << path
        end
      
        def gemfile
          copy_file 'files/Gemfile', 'Gemfile'
        end
      

      然后在控制台上:

      rails new my_app -b path_to_app_builder.rb

      这些点是必需的,因为在rails new 命令更改为新的应用程序目录(我认为)之后,ruby 文件“app_builder.rb”被吞并并评估。

      【讨论】:

        【解决方案3】:

        Thor 将访问您的 source_paths 方法并将这些添加到默认值:

          # Returns the source paths in the following order:
          #
          #   1) This class source paths
          #   2) Source root
          #   3) Parents source paths
          #
          def source_paths_for_search
            paths = []
            paths += self.source_paths
            paths << self.source_root if self.source_root
            paths += from_superclass(:source_paths, [])
            paths
          end
        

        所以你在课堂上需要做的就是:

        class NewgemGenerator < Thor::Group
        
          include Thor::Actions
        
          def source_paths
            ['/whatever', './templates']
          end
        
        end
        

        希望这会有所帮助:)

        【讨论】:

        • 我试过了,我仍然得到这个错误:Could not find "&lt;any_file&gt;" in any of your source paths. Your current source paths are: path/to/gems/railties-3.2.2/lib/rails/generators/rails/app/templates,所以它根本没有捡起它。
        • 我添加了类定义并将我使用的答案包含在内。
        • 但我必须继承 Rails::AppBuilder,因为我覆盖了该类生成的内容。
        • 我会给你赏金,所以它不会浪费。
        • 谢谢!祝你的项目好运。
        【解决方案4】:

        这行得通:

        require 'thor'
        require 'rails/generators/rails/app/app_generator'
        
        module Thor::Actions
          def source_paths
            [MY_TEMPLATES]
          end
        end
        
        class AppBuilder < Rails::AppBuilder
          ...
        end
        

        我不明白为什么,但我已经花了太多时间在这上面,所以我不在乎。

        【讨论】:

          猜你喜欢
          • 2022-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-21
          • 2011-11-18
          • 1970-01-01
          • 2012-06-07
          • 1970-01-01
          相关资源
          最近更新 更多