Search code examples
ruby-on-railsrubythor

How to use Thor::Shell::Basic in a Rails Generator?


I am writing a Rails 3.2 generator and would like to use Thor::Shell::Basic instance methods (e.g. ask or yes?) like they do in the official Rails guides on Application Templates.

module MyNamespace
  class ScaffoldGenerator < Rails::Generators::Base
    source_root File.expand_path('../templates', __FILE__)

    if yes? "Install MyGem?"
      gem 'my_gem'
    end

    run 'bundle install'
  end
end

This will give me a NoMethodError: undefined method 'yes?' for MyNamespace::ScaffoldGenerator:Class.

I cannot figure out a clean way to make those instance methods available - I am already inheriting from Rails::Generators::Base.

Edit:

Ah, it probably has nothing to do with Thor... I get a warning:

[WARNING] Could not load generator "generators/my_namespace/scaffold/scaffold_generator"

Something is not set up correctly although I used the generator for generating generators...


Solution

  • Oh, yes, it does have to do something with Thor.

    Do not let yourself get confused by the warning. You know that Rails::Generators uses Thor, so walk over to the Thor Wiki and check out how Thor tasks work.

    The rails generator execution will call any method in your generator. So make sure that you organize your stuff into methods:

    module MyNamespace
      class ScaffoldGenerator < Rails::Generators::Base
        source_root File.expand_path('../templates', __FILE__)
    
        def install_my_gem
          if yes? "Install MyGem?"
            gem 'my_gem'
          end
        end
    
        def bundle
          run 'bundle install'
        end
      end
    end
    

    Be sure to put your generator into the right folder structure, e.g. lib/generators/my_namespace/scaffold_generator.rb.

    Thanks for asking your question, dude!