如何编写一个会覆盖默认脚手架javascript文件的rails生成器?

时间:2017-07-21 11:14:42

标签: ruby-on-rails ruby-on-rails-5 rails-generators

背景:

  • 目前正在写一个宝石
  • 其中一个功能是,当rails generate my_gem_name:install运行时,它(应该)覆盖默认的javascript scaffold生成的文件(由rails generate scaffold some_model_name生成):

    • app/assets/javascripts/some_model_name.coffee

      • 发件人:

        # Place all the behaviors and hooks related to the matching controller here.
        # All this logic will automatically be available in application.js.
        # You can use CoffeeScript in this file: http://coffeescript.org/
        
      • # Place all the behaviors and hooks related to the matching controller here.
        # All this logic will automatically be available in application.js.
        # You can use CoffeeScript in this file: http://coffeescript.org/
        
        SomeJavascriptCode.doSomething({model: 'SomeModelName'})
        

问题:

  • 如何编写上述Rails生成器(从上面),它将覆盖由rails generate scaffold some_model_name创建的默认脚手架javascript文件。
  • 请注意,所需的javascript文件(如上所示)具有动态内容;那个{model: 'SomeModelName'}应该改变&与正在生成的型号名称正确匹配。

尝试:

  • 我意识到解决这个问题有两个步骤:

    • 只是能够覆盖脚手架生成的javascript文件

    • 然后,做一些能够使所生成的javascript文件的内容生成的内容,以及" dynamic"内容。

  • 第一步

    • 尝试编写一个将我的模板文件复制到Rails' AssetsGenerator模板,最终(希望)覆盖它。

      # lib/generators/my_gem_name/install_generator.rb
      module MyGemName
        class InstallGenerator < Rails::Generators::Base
          source_root File.expand_path('../templates', __FILE__)
      
          class_option :javascript_engine, desc: 'JS engine to be used: [js, coffee].'
      
          def copy_js_scaffold_template
            copy_file "javascript.#{javascript_engine}", "lib/templates/coffee-rails/assets/javascript.#{javascript_engine}"
          end
      
          private
      
          def javascript_engine
            options[:javascript_engine]
          end
        end
      end
      
      # lib/generators/my_gem_name/templates/javascript.coffee
      console.log('JUST TESTING!!!!!!!')
      
      • 我暂时使用路径 lib / templates / coffee-rails / assets / javascript.coffee 来测试它,因为默认javascript_enginecoffee 。可能应该根据--javascript_engine)进行更改,但似乎无法使其正常工作。 我从此LINK获得此路径,然后引用THIS

          

        似乎模式正在流动:   LIB /模板/ gem_name / generator_name / template_file_name.rb

      • 从这个LINK,我也尝试使用路径(但没有用):

        • LIB /模板/轨道/资产/ javascript.coffee
        • 的lib /模板/导轨/资产/咖啡/ javascript.coffee
    • 第二步:到目前为止还没有尝试过,因为我想先将第一步作为第一步。

      < / LI>

我上面的所有尝试都不起作用:就是在rails generate my_gem_name:install运行之后,运行rails generate scaffold some_model_name仍会生成原始的默认javascript文件,而不是预期的{ {1}}内容(如上所述)

1 个答案:

答案 0 :(得分:0)

我终于通过以下方式解决了这个问题。希望它对任何人都有帮助:

对于第1步(覆盖javascript文件):

  • 问题是覆盖路径不是

    lib/templates/gem_name/generator_name/template_file_name.rb

    lib/templates/module_name/generator_name/template_file_name.rb

    我在查看Coffe-Rails Generator Code之后验证了这一点,然后尝试了以下(有效:脚手架生成的javascript文件现在在运行rails generate my_gem_name:install之后被覆盖,然后是脚手架生成器{{1} })

    rails generate scaffold some_model_name

对于第2步(动态javascript文件内容):

  • 经过一些反复试验后,我发现您实际上可以在javascript文件中插入# I temporarily hardcoded `coffee` as the `javascript_engine` to demonstrate, but `js` also works. copy_file "javascript.coffee", "lib/templates/coffee/assets/javascript.coffee" ,然后将模板重命名为<%= ... %>文件扩展名。当您在文件中插入ruby时,template看起来就像Rails视图的工作方式一样呈现。

完整的解决方案如下:

<强> LIB /发电机/ my_gem_name / install_generator.rb

<%= ... %>

<强> LIB /发电机/ my_gem_name /模板/ javascript.coffee.rb

module MyGemName
  class InstallGenerator < Rails::Generators::Base
    source_root File.expand_path('../templates', __FILE__)

    class_option :javascript_engine, desc: 'JS engine to be used: [js, coffee].'

    def copy_js_scaffold_template
      copy_file "javascript.#{javascript_engine}.rb", "lib/templates/#{javascript_engine}/assets/javascript.#{javascript_engine}"
    end

    private

    def javascript_engine
      options[:javascript_engine]
    end
  end
end

然后,在终端上:

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
SomeJavascriptCode.doSomething({model: '<%= singular_table_name.camelcase %>'})