问题描述
当你想重写一个生成器模板(不用替换生成器本身)时,在Rails 3中,你可以将文件放在lib / templates中适当命名的地方,Rails会找到它们。如果你想用宝石做到这一点,该怎么办?我试图采取我团队的标准化脚手架格式并进行gemify,以便我们可以在所有项目中共享它并轻松更新,而不是将文件复制到每个项目的lib /中。这适用于我创建了新的生成器的情况,我用application.rb中的config.generators钩住它,Rails找到它。但是,当我将模板文件放入 gem 中的lib / templates中时,Rails首先找到它自己的默认模板,然后渲染它们而不是我的模板。我认为搜索顺序是RAILS_ROOT / lib / templates,RAILS_GEMS / lib / templates,OTHER_GEMS / lib / templates。
解决方案是什么?我在这方面没有找到太多docco,通过Rails进行代码潜水并没有提出明显的解决方案。谢谢!
我们知道了这一点。生成器配置有一个'模板'变量,列出了模板的搜索路径。问题的确在于它会按顺序搜索这个数组,直到找到匹配项,所以您的应用程序或Rails中的模板将在您的gem中的模板之前找到。
解决方案是让你的宝石的Railtie将模板路径放到模板路径数组的开始上。它看起来像这样。该文件位于[GEM] /lib/my_gem.rb中。这些模板与[GEM] / lib / templates /中的模板是平行的。
module MyGem
class Railtie< Rails :: Railtie
config.generators do | g |
g.templates.unshift File :: expand_path('../ templates',__FILE__)
end
end
end
如果模板在[GEM] / lib / templates内有一个与您要覆盖的默认模板路径相匹配的路径,则应该可以工作。例如,如果您已完成此操作并创建了[GEM] /lib/templates/active_record/model/model.rb,则它将覆盖默认的AR模型模板。
编辑:请注意,由于此答案最初发布时,config.generators已被删除来自Rails。使用 config.app_generators
代替pixelearth的回答。
When you want to override a generator template (without replacing the generator itself), in Rails 3 you can just drop files in appropriately named places in lib/templates and Rails will find them.
What if you want to do this with a gem? I'm trying to take my team's standardized scaffold format and gemify it so we can share it in all projects and update it easily, rather than copy files into lib/ in every project. This works fine for the cases where I've created a new generator; I hook into it with config.generators in application.rb and Rails finds it. But when I drop template files into lib/templates in the gem, Rails finds its own default templates first, and renders them instead of mine. I think the search order is RAILS_ROOT/lib/templates, RAILS_GEMS/lib/templates, OTHER_GEMS/lib/templates.
What's the solution? I'm not finding much docco on this, and code-diving through Rails hasn't presented an obvious solution. Thanks!
We figured this out. the generators config has a 'templates' variable that lists search paths for templates. The problem is indeed that it searches this array in order until it finds a match, so templates in your app or in Rails will get found before templates in your gem.
The solution is to have your gem's Railtie put the templates path onto the beginning of the array of template paths. It looks like this. This file is in [GEM]/lib/my_gem.rb. The templates are parallel to it in [GEM]/lib/templates/.
module MyGem
class Railtie < Rails::Railtie
config.generators do |g|
g.templates.unshift File::expand_path('../templates', __FILE__)
end
end
end
If the templates have a path inside [GEM]/lib/templates that matches the path of the default template you are overriding, this should work. For example, if you've done this and you create [GEM]/lib/templates/active_record/model/model.rb, it will override the default AR model template.
No monkeypatching of the generators required.
EDIT: Note that since this answer was originally posted, "config.generators" has been removed from Rails. Use config.app_generators
instead as per pixelearth's answer below.
这篇关于如何覆盖宝石中的轨道生成器模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!