Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get generators call other generators in rails 3

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!

like image 959
Ben Avatar asked May 04 '11 22:05

Ben


3 Answers

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:

Rails 3 generators in gem

like image 162
Mike Farmer Avatar answered Oct 12 '22 00:10

Mike Farmer


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.

like image 23
Julian Kniephoff Avatar answered Oct 12 '22 00:10

Julian Kniephoff


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.)

like image 44
monocle Avatar answered Oct 12 '22 00:10

monocle