I'm writing a Rails 3 generator that creates two different models. Here's a very simplified example of what I'm trying to do:
def my_generator_task
invoke "model", ["foo"]
invoke "model", ["bar"]
end
The problem is that the Thor invoke method only invokes a task once, so the second call to the "model" task never happens and the "bar" model is never created. Does anyone know an elegant way to accomplish this, preferably in a way that doesn't break the ability to run "rails destroy" with the generator?
One more thought, this way it is also possible to run multiple model generator without migration
Rails::Generators.invoke("active_record:model", ["foo", "--no-migration" ])
Rails::Generators.invoke("active_record:model", ["bar", "--no-migration" ])
With Thor, if you want to invoke a task withOUT dependency management, you just call it directly:
model(foo)
model(bar
In case you want to run a generator that subclasses from Thor::Group, i.e. not just a single Thor task, you can invoke an entire generator from any different file.
Rails::Generators.invoke("my_generator", my_generator_args)
The generators module generators.rb in railties/rails seems to create a new instance, so it doesn't think that the task has already been called. This means you can repeat the above line as many times as you want and it will run each time.
I don't know of an elegant way to do that. In this talk, I gave an example of a custom generator that invokes the controller
generator twice - check out slide 43.
The inelegant way is to go into Thor's @_invocations
array and delete the first run's tasks before running it again.
there is a macro method called "behavior" can help(using bonyiii's example):
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
or just:
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