Ruby on rails 使用rails生成器修改文件

Ruby on rails 使用rails生成器修改文件,ruby-on-rails,generator,Ruby On Rails,Generator,如何制作更改文件的生成器 我试图使它在文件中找到一个模式,并将内容添加到下面的行中。Rails的脚手架生成器在向config/routes.rb添加路由时执行此操作,它调用一个非常简单的方法: def gsub_file(relative_destination, regexp, *args, &block) path = destination_path(relative_destination) content = File.read(path).gsub(regexp, *

如何制作更改文件的生成器


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

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\u path
,因此您可能希望传入确切的路径并跳过任何转换

要使用
gsub_文件
,假设您希望向用户模型添加标记。以下是您将如何做到这一点:

line = "class User < ActiveRecord::Base"
gsub_file 'app/models/user.rb', /(#{Regexp.escape(line)})/mi do |match|
  "#{match}\n  has_many :tags\n"
end
line=“class User
您在文件中找到了特定的行,即类开场白,并在下面添加了许多


但是要小心,因为这是添加内容最脆弱的方式,这就是为什么路由是唯一使用它的地方之一。上面的例子通常是混合处理的。

我喜欢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生成器运行多次,我将重复插入。因此,我将代码包装在
块中,除非

最后,我为您添加了
def destination\u path()

现在,您将如何在rails生成器中使用它?以下是我如何确保为rspec和cucumber安装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
也许有一种更优雅、更干练的方法可以做到这一点。我真的很喜欢你如何添加杰米例子中的文本块。希望我的示例添加了更多的功能和错误检查