2010-12-02 11 views
10

J'écris un générateur Rails 3 qui crée deux modèles différents. Voici un exemple très simplifié de ce que je suis en train de faire:Tâche d'appel plus d'une fois dans le générateur Rails 3

def my_generator_task 
    invoke "model", ["foo"] 
    invoke "model", ["bar"] 
end 

Le problème est que la Thor invoke method invoque seulement une tâche une fois, de sorte que le deuxième appel au « modèle » tâche ne se reproduise jamais et le « bar » le modèle n'est jamais créé. Est-ce que quelqu'un sait une manière élégante d'accomplir ceci, de préférence d'une manière qui ne casse pas la capacité de courir "des rails détruisent" avec le générateur?

Répondre

2

Avec Thor, si vous voulez invoquer une tâche, vous appelez simplement directement la dépendance sans gestion:

model(foo) 
model(bar 
1

Si vous voulez exécuter un générateur de Thor :: sous-classes du groupe, à savoir non seulement une seule tâche Thor, vous pouvez appeler un générateur entier à partir de n'importe quel fichier différent.

Rails::Generators.invoke("my_generator", my_generator_args) 

Le module generators.rb dans railties/rails semble créer une nouvelle instance générateurs, donc il ne pense pas que la tâche a déjà été appelé. Cela signifie que vous pouvez répéter la ligne ci-dessus autant de fois que vous le souhaitez et il fonctionnera à chaque fois.

1

Je ne connais pas une façon élégante de le faire. En this talk, j'ai donné un exemple d'un générateur personnalisé qui appelle le générateur controller deux fois - consultez diapositive 43.

La façon inélégante est d'aller dans un tableau de Thor @_invocations et supprimer la première des tâches de exécution avant de l'exécuter à nouveau.

+0

+1 - après 'invoquer: méthode, [arguments], options' utiliser' @ _invocations.first [1] .pop' à enlev e la tâche la plus récemment appelée dans la liste d'invocation. – Andy

3

plus une pensée, de cette façon, il est également possible d'exécuter plusieurs générateur de modèles sans migration

Rails::Generators.invoke("active_record:model", ["foo", "--no-migration" ]) 
Rails::Generators.invoke("active_record:model", ["bar", "--no-migration" ]) 
0

il existe une méthode macro appelée « comportement » peut aider (en utilisant l'exemple de bonyiii):

def generate_model 
    if behavior == :invoke 
    Rails::Generators.invoke("active_record:model", ["foo", "--no-migration"], behavior: behavior) 
    Rails::Generators.invoke("active_record:model", ["bar", "--no-migration"], behavior: behavior) 
    else # behavior == :revoke 
    Rails::Generators.invoke("active_record:model", ["foo", "--no-migration"], behavior: :revoke) 
    Rails::Generators.invoke("active_record:model", ["bar", "--no-migration"], behavior: :revoke) 
    end 
end 

ou tout simplement:

def generate_model 
    Rails::Generators.invoke("active_record:model", ["foo", "--no-migration"], behavior: behavior) 
    Rails::Generators.invoke("active_record:model", ["bar", "--no-migration"], behavior: behavior) 
end