Reputation: 563
I am experimenting with gem development, right now specifically generators. So far I have successfully created two generators that do their job just perfectly. These two generators are in the same directory.
However, right now I have to call each of them separately.
What I'd like to do is just call one generator and have that generator call all the other ones. Just would type
rails g generator_name
and this would call x other generators.
Does anyone know how would I got about doing this?
Help is much appreciated, thanks!
Upvotes: 14
Views: 4071
Reputation: 5896
Generators are based off of Thor, so you can use the apply method.
This is what the Rails Templater gem does. (Here's a walk through the Rails Templater gem.)
Upvotes: 1
Reputation: 1023
Another possibility is to use something like
invoke 'active_record:model', 'foo bar:string baz:float'
which is not as clean as generate
, but has one advantage: When your generator gets called via rails destroy
, this call -- like may other of Thors actions -- will try to revoke the action of the generator you invoke
.
There's a catch however: Probably due to Thors dependency management, this only works once per generator you want to call, meaning that a second invoke
of the same generator will do nothing. This can be circumvented by using a statement like
Rails::Generators.invoke 'active_record:model', '...', behavior: behavior
instead. In this case you have to explicitly pass through the behavior
of your generator (which is a method returning values like :invoke
, :revoke
and possibly others, depending on which command -- rails generate
, rails destroy
, rails update
, etc. -- called your generator) to achieve the same result as above. If you don't do this, the generator you call with Rails::Generators.invoke
will also be executed when running your generator with rails destroy
.
Alternatively you could stick to invoke
and try to tamper with Thors invocation system. See also here for example.
Upvotes: 9
Reputation: 2992
In your generator, you can just call
generate "some:generator" # can be anything listed by 'rails g'
for example:
module MyGem
class InstallGenerator < Rails::Generators::Base
def run_other_generators
generate "jquery:install" # or whatever you want here
end
end
end
By the way, if you are working on Rails 3 gems, this question can also help out:
Upvotes: 23
Reputation: 3866
Take a look at the scaffold generator that comes with rails.
/Users/XYZ/sources/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
def manifest
record do |m|
#....rest of the source is removed for brevity....
m.dependency 'model', [name] + @args, :collision => :skip
end
end
Here the scaffold generator is using the model generator. So take a look at the dependency method. You can find the API docs for it over here.
Upvotes: 0