代码之家  ›  专栏  ›  技术社区  ›  Arcath

使用rails生成器修改文件

  •  12
  • Arcath  · 技术社区  · 16 年前

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

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

    2 回复  |  直到 16 年前
        1
  •  16
  •   Jaime Bellmyer    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 线就在下面。

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

        2
  •  2
  •   Eric Wanchic    13 年前

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

    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 相反

    unless 块

    最后,我添加了 def destination_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
    

    也许有一种更优雅、更干练的方法可以做到这一点。我真的很喜欢你如何添加杰米例子中的文本块。希望我的示例添加了更多的功能和错误检查。