2010-01-18 33 views

回答

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 

它在做什麼正在採取的路徑/文件作爲第一個參數,其次是一個正則表達式模式,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

我喜歡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代替。

接下來,我需要檢查替換字符串是否已經就位。否則,我會重複插入,如果我的軌道發電機多次運行。所以我將代碼包裝在unless區塊中。

最後,我爲您添加了def destination_path()

現在,你將如何在軌道發電機中使用它?下面是我如何才能確保simplecov安裝了RSpec的,黃瓜爲例:

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 

有可能是一個更優雅和DRY-ER的方式來做到這一點。我真的很喜歡你如何添加一塊Jamie的例子。希望我的例子增加了一些功能和錯誤檢查。