2010-01-18 6 views

Répondre

16

Rails générateur de l'échafaudage fait quand il ajoute une route vers config/routes.rb Elle le fait en appelant une méthode très 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 

Qu'est-ce qu'il fait est de prendre un chemin/fichier comme premier argument, suivi par un motif regexp, des arguments gsub et le bloc. C'est une méthode protégée que vous devrez recréer pour pouvoir l'utiliser. Je ne sais pas si vous aurez accès à destination_path, alors vous voudrez probablement passer le chemin exact et ignorer toute conversion.

Pour utiliser gsub_file, disons que vous souhaitez ajouter des balises à votre modèle utilisateur. Voici comment vous le faire:

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

vous trouvez la ligne spécifique dans le fichier, l'ouvreur de classe, et en ajoutant votre has_many ligne droite au-dessous. Mais attention, parce que c'est le moyen le plus fragile d'ajouter du contenu, c'est pourquoi le routage est l'un des seuls endroits qui l'utilise. L'exemple ci-dessus serait normalement géré avec un mix-in.

1

J'aime la réponse de Jaime. Mais, quand j'ai commencé à l'utiliser, j'ai réalisé que j'avais besoin de faire quelques modifications. Voici l'exemple de code J'utilise:

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 premier lieu, gsub remplacera toutes les instances du texte de recherche; J'ai seulement besoin d'un. J'ai donc utilisé sub à la place.

Ensuite, j'ai dû vérifier si la chaîne de remplacement était déjà en place. Sinon, je répéterais l'insertion si mon générateur de rails a été exécuté plusieurs fois. J'ai donc enveloppé le code dans un bloc unless. J'ai enfin ajouté le def destination_path() pour vous.

Maintenant, comment l'utiliseriez-vous dans un générateur de rails? Voici un exemple de la façon dont je fais simplecov vous est installé pour rspec et concombre:

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 

Il y a probablement une façon plus élégante et DRY-er pour le faire. J'ai vraiment aimé comment ajouter un bloc de texte à l'exemple de Jamie. J'espère que mon exemple ajoute un peu plus de fonctionnalité et de vérification d'erreurs.

Questions connexes