2

背景:

  • 目前正在写一个gem
  • 它的特点之一是在rails generate my_gem_name:install运行时,它(应该)覆盖默认的 javascript 脚手架生成的文件(由 生成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 文件(如上所示)具有动态内容;那{model: 'SomeModelName'}应该与正在生成的模型名称正确更改和匹配。

尝试:

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

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

    • 然后,做一些事情,使所述生成的 javascript 文件的内容具有“动态”内容。

  • 第一步

    • 尝试编写一个生成器,将我的模板文件复制到 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/templates/gem_name/generator_name/template_file_name.rb

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

        • lib/templates/rails/assets/javascript.coffee
        • lib/templates/rails/assets/coffee/javascript.coffee
    • 第二步:到目前为止还没有尝试,因为我想先做上面的第一步

我上面的所有尝试都不起作用:即在两者rails generate my_gem_name:install都运行之后,然后运行rails generate scaffold some_model_name仍然会产生原始的默认 javascript 文件,而不是预期的console.log('JUST TESTING!!!!!!!')内容(如上所述)

4

1 回答 1

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 生成器代码然后尝试以下方法后验证了这一点(有效:脚手架生成的 javascript 文件现在在运行后被覆盖,rails generate my_gem_name:install然后是脚手架生成器rails generate scaffold some_model_name

    # I temporarily hardcoded `coffee` as the `javascript_engine` to demonstrate, but `js` also works.
    copy_file "javascript.coffee", "lib/templates/coffee/assets/javascript.coffee"
    

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

  • 经过反复试验,我注意到您实际上可以<%= ... %>在 javascript 文件中插入,然后将模板重命名为ruby文件扩展名。当您在文件中template插入时,看起来就像 Rails 视图的工作方式一样呈现。<%= ... %>

完整的解决方案如下所示:

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}.rb", "lib/templates/#{javascript_engine}/assets/javascript.#{javascript_engine}"
    end

    private

    def javascript_engine
      options[:javascript_engine]
    end
  end
end

lib/generators/my_gem_name/templates/javascript.coffee.rb

# 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 %>'})

然后,在终端上:

rails generate my_gem_name:install
  Running via Spring preloader in process 42586
        create lib/templates/coffee/assets/javascript.coffee

rails generate scaffold user email first_name last_name
  Running via Spring preloader in process 43054
        invoke active_record
        create   db/migrate/20170721152013_create_users.rb
        create   app/models/user.rb
        ...
        invoke assets
        invoke   coffee
        create     app/assets/javascripts/users.coffee
        ...

cat app/assets/javascripts/users.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/
  SomeJavascriptCode.doSomething({model: 'User'})
于 2017-07-21T20:08:43.343 回答