如何编写一个 rails 生成器来覆盖默认脚手架 javascript 文件?
How to write a rails generator that would override the default scaffold javascript file?
背景:
- 目前正在写一个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 文件
- 请注意,所需的 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_engine
是coffee
.可能这应该根据 --javascript_engine
) 而改变,但似乎无法使其工作。
我从这个 LINK and then by referencing THIS:
得到了这条路径
It seems that the pattern is flowing:
lib/templates/gem_name/generator_name/template_file_name.rb
从这个 LINK,我也尝试使用路径(但没有用):
- lib/templates/rails/assets/javascript.咖啡
- lib/templates/rails/assets/coffee/javascript.咖啡
第二步: 到目前为止还没有尝试,因为我想在上面进行 第一步先工作
我上面的所有尝试都不起作用:即在 rails generate my_gem_name:install
是 运行 之后,然后 运行ning rails generate scaffold some_model_name
仍然产生原始默认 javascript 文件,而不是预期的 console.log('JUST TESTING!!!!!!!')
内容(如上所述)
我终于通过以下解决了。希望这对任何人都有帮助:
对于第 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
之后被覆盖然后是脚手架生成器 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'})
背景:
- 目前正在写一个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 文件
- 请注意,所需的 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_engine
是coffee
.可能这应该根据--javascript_engine
) 而改变,但似乎无法使其工作。 我从这个 LINK and then by referencing THIS:It seems that the pattern is flowing: lib/templates/gem_name/generator_name/template_file_name.rb
从这个 LINK,我也尝试使用路径(但没有用):
- lib/templates/rails/assets/javascript.咖啡
- lib/templates/rails/assets/coffee/javascript.咖啡
第二步: 到目前为止还没有尝试,因为我想在上面进行 第一步先工作
我上面的所有尝试都不起作用:即在 rails generate my_gem_name:install
是 运行 之后,然后 运行ning rails generate scaffold some_model_name
仍然产生原始默认 javascript 文件,而不是预期的 console.log('JUST TESTING!!!!!!!')
内容(如上所述)
我终于通过以下解决了。希望这对任何人都有帮助:
对于第 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
之后被覆盖然后是脚手架生成器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'})