使用rails生成器修改文件

时间:2010-01-18 18:58:41

标签: ruby-on-rails generator

如何制作改变文件的生成器。

我试图让它在文件中找到一个模式,并将内容添加到它下面的行。

2 个答案:

答案 0 :(得分:16)

Rails'脚手架生成器在向config/routes.rb添加路由时执行此操作。它通过调用一个非常简单的方法来实现:

def gsub_file(relative_destination, regexp, *args, &block)
  path = destination_path(relative_destination)
  content = File.read(path).gsub(regexp, *args, &block)
  File.open(path, 'wb') { |file| file.write(content) }
end

它正在做的是将路径/文件作为第一个参数,然后是regexp模式,gsub参数和块。这是一种受保护的方法,您必须重新创建才能使用。我不确定destination_path是否是您可以访问的内容,因此您可能希望传递确切的路径并跳过任何转换。

要使用gsub_file,假设您要为用户模型添加标记。这是你如何做到的:

line = "class User < ActiveRecord::Base"
gsub_file 'app/models/user.rb', /(#{Regexp.escape(line)})/mi do |match|
  "#{match}\n  has_many :tags\n"
end

您正在文件中找到特定的行,开启者,并在下方添加has_many行。

请注意,因为这是添加内容最脆弱的方式,这就是路由是唯一使用它的地方之一。上面的例子通常会用混合处理。

答案 1 :(得分:1)

我喜欢Jaime的回答。但是,当我开始使用它时,我意识到我需要做一些修改。以下是我使用的示例代码:

private

  def destination_path(path)
    File.join(destination_root, path)
  end

  def sub_file(relative_file, search_text, replace_text)
    path = destination_path(relative_file)
    file_content = File.read(path)

    unless file_content.include? replace_text
      content = file_content.sub(/(#{Regexp.escape(search_text)})/mi, replace_text)
      File.open(path, 'wb') { |file| file.write(content) }
    end

  end

首先,gsub将替换搜索文本的所有实例;我只需要一个。因此,我使用sub代替。

接下来,我需要检查替换字符串是否已经到位。否则,如果我的rails生成器多次运行,我会重复插入。所以我将代码包装在unless块中。

最后,我为您添加了def destination_path()

现在,您如何在轨道生成器中使用它?以下是我如何确保为rspec和黄瓜安装simplecov的示例:

  def configure_simplecov
    code = "#Simple Coverage\nrequire 'simplecov'\nSimpleCov.start"

    sub_file 'spec/spec_helper.rb', search = "ENV[\"RAILS_ENV\"] ||= 'test'", "#{search}\n\n#{code}\n"
    sub_file 'features/support/env.rb', search = "require 'cucumber/rails'", "#{search}\n\n#{code}\n"
  end

这可能是一种更优雅,更干燥的方式。我真的很喜欢你如何添加Jamie的例子。希望我的示例添加更多功能和错误检查。