简体   繁体   English

如何更改自定义导轨生成器的源? (雷神)

[英]How to change source for a custom rails generator? (Thor)

I'm making a custom generator that generates a new rails app, and I do it like this我正在制作一个生成新 Rails 应用程序的自定义生成器,我这样做

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

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

The problem is, how do I add a new source directory (which is then used by Thor::Actions#copy_file , Thor::Actions#template , and the others)?问题是,我如何添加一个新的源目录(然后由Thor::Actions#copy_fileThor::Actions#template和其他人使用)? I saw in the Thor's documentation that Thor::Actions#source_paths holds the sources (it's an array of paths), so I tried overriding it inside my class (since I've included Thor::Actions ):我在 Thor 的文档中看到Thor::Actions#source_paths保存源(它是一个路径数组),所以我尝试在我的类中覆盖它(因为我已经包含了Thor::Actions ):

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

With this I wanted to add the ./templates directory in the sources, while still keeping the Rails' one (that's why the + super at the end).有了这个,我想在源代码中添加./templates目录,同时仍然保留 Rails 的目录(这就是为什么最后加上+ super的原因)。 But it doesn't work, it still lists the Rails' source path as the only one.但是它不起作用,它仍然将Rails的源路径列为唯一的。

I tried browsing through the Rails' source code, but I couldn't find how Rails put his directory in the source paths.我尝试浏览 Rails 的源代码,但我找不到 Rails 如何将他的目录放在源路径中。 And I really want to know that :)我真的很想知道:)

This worked:这有效:

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

module Thor::Actions
  def source_paths
    [MY_TEMPLATES]
  end
end

class AppBuilder < Rails::AppBuilder
  ...
end

I don't understand why, but I've spent too much time on this already, so I don't care.我不明白为什么,但我已经花了太多时间在这上面,所以我不在乎。

Thor will access your source_paths method and add these to the defaults: 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

So all you need to do in your class is:所以你在课堂上需要做的就是:

class NewgemGenerator < Thor::Group

  include Thor::Actions

  def source_paths
    ['/whatever', './templates']
  end

end

Hope this helps :)希望这可以帮助 :)

The source_paths method doesn't work when using AppBuilder.使用 AppBuilder 时 source_paths 方法不起作用。 (which is another option to using rails templates). (这是使用 rails 模板的另一种选择)。 I have a files directory next to the app_builder.rb file that this class is in. I have this working, though it seems there should still be a more elegant way.我在这个类所在的 app_builder.rb 文件旁边有一个文件目录。我有这个工作,但似乎仍然应该有一个更优雅的方式。

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

and then on the console:然后在控制台上:

rails new my_app -b path_to_app_builder.rb

The dots are required since the ruby file 'app_builder.rb' is slurped up and eval'd after the rails new command changes into the new app directory (I think).这些点是必需的,因为在rails new命令更改为新的应用程序目录(我认为)之后,ruby 文件“app_builder.rb”被删除并评估。

It's an old post, however, the problem remains the same, I spent time to figure that out.这是一个旧帖子,但是,问题仍然存在,我花了一些时间来解决这个问题。 I let a comment here if it can help.如果有帮助,我在这里发表评论。

Rails add by default the path lib/templates so you can custom any templates by copying them in this directory. Rails 默认添加路径lib/templates因此您可以通过将它们复制到此目录中来自定义任何模板。

Check out the correct directories structures https://github.com/rails/rails/tree/v6.0.1/railties/lib/rails/generators/rails查看正确的目录结构https://github.com/rails/rails/tree/v6.0.1/railties/lib/rails/generators/rails

There is subtle though and is not so obvious to catch.虽然有微妙之处,但不是很明显。

Take for instance the helper generator, as mentioned in the official Rails documentation, the structure ishelper生成器为例,Rails 官方文档中提到,其结构为

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

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

Here, what Railties expects to find in your project:在这里, Railties希望在您的项目中找到的内容:

- lib
  - templates 
    - helper
      - helper.rb

your helper.rb is a copy of helper.rb.tthelper.rb是副本helper.rb.tt

the last thing, if you plan to use it in Rails::Engine you have to tell it to load that path最后一件事,如果你打算在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

Really hope that can help and save time for others.真心希望能帮到别人,节省时间。

  1. https://github.com/rails/rails/blob/v6.0.1/railties/lib/rails/application/configuration.rb#L188 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 https://guides.rubyonrails.org/generators.html#customizing-your-workflow-by-changed-generators-templates
  3. https://github.com/rails/rails/blob/v6.0.1/railties/CHANGELOG.md https://github.com/rails/rails/blob/v6.0.1/railties/CHANGELOG.md
  4. https://guides.rubyonrails.org/engines.html https://guides.rubyonrails.org/engines.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM