2010-01-18 15 views

Respuesta

16

Rails hace esto cuando se agrega una ruta a config/routes.rb Esto lo hace llamando a un método muy simple:

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 

Lo que está haciendo es tomar una ruta/archivo como primer argumento, seguido de un patrón regexp, argumentos gsub y el bloque. Este es un método protegido que deberá recrear para usar. No estoy seguro de si destination_path es algo a lo que tendrá acceso, por lo que probablemente desee pasar la ruta exacta y omitir cualquier conversión.

Para usar gsub_file, supongamos que desea agregar etiquetas a su modelo de usuario. He aquí cómo lo haría:

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

Usted está encontrando la línea específica en el archivo, el primer partido de la clase, y la adición de su línea has_many justo debajo.

Tenga cuidado, porque esta es la forma más frágil de agregar contenido, razón por la cual el enrutamiento es uno de los únicos lugares que lo usa. El ejemplo anterior normalmente se manejaría con un mix-in.

1

Me gusta la respuesta de Jaime. Pero cuando comencé a utilizarlo, me di cuenta de que necesitaba hacer algunas modificaciones. Aquí está el código de ejemplo que estoy utilizando:

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 

En primer lugar, gsub sustituirá todos los casos del texto de búsqueda; Solo necesito uno. Por lo tanto, usé sub en su lugar.

A continuación, necesitaba comprobar si la cadena de reemplazo ya estaba en su lugar. De lo contrario, estaría repitiendo el inserto si mi generador de rieles se ejecutara varias veces. Así que envolví el código en un bloque unless.

Finalmente, agregué el def destination_path() para usted.

Ahora, ¿cómo usarías esto en un generador de rieles? Aquí está un ejemplo de cómo me aseguro simplecov está instalado para rspec y pepino:

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 

es probable que haya una forma más elegante y seco-er para hacer esto. Me gustó mucho cómo puedes agregar un bloque de texto al ejemplo de Jamie. Espero que mi ejemplo agregue un poco más de funcionalidad y comprobación de errores.

Cuestiones relacionadas