How to get generators call other generators in rails 3
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
Fixing Rails generator issues: calling same generator twice no-ops and exits 0 without running 2nd generator
Turns out the problem lies in Thor - it will only read the first invoke
statement in any generator. Found the solution in this answer to a question about rails 3 generators - turns out it hasn't changed since.
Quoting the original answer:
"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
"
So replacing invoke
with Rails::Generators.invoke
totally did the trick.
Running other generator within a generator
You must define a hook_for
the other generator in your generator class. The ScaffoldGenerator
is probably the best example of this, as it has a hook for the scaffold_controller
generator.
If you want to pass in arguments to your generator, it's probably better to use something like the hook_for
examples further down in this file for assets and stylesheet engine.
Rails Gem: Running All Generators for given Namespace
Keep an "AllGenerator" class under Admin module. The generator will have to do the following :
- For each class under the namespace that is a generator class,
- get the namespace from classname.
- Call the
invoke
method with the namespace.
Something like this :
module Admin
module Generators
class AllGenerator < Rails::Generators::Base
def generator
Rails::Generators.lookup!
Admin::Generators.constants.each do |const|
generator_class = Admin::Generators.const_get(const)
next if self.class == generator_class
if generator_class < Rails::Generators::Base
namespace = generator_klass_to_namespace(generator_class)
invoke(namespace)
end
end
end
private
def generator_klass_to_namespace(klass)
namespace = Thor::Util.namespace_from_thor_class(klass)
return namespace.sub(/_generator$/, '').sub(/:generators:/, ':')
end
end
end
end
Here's the link to the gist with complete tested code
This way, running rails g admin:all
would run every other generator directly under Admin::Generators
.
How to invoke generators from code?
Solution appears to be pretty simple:
This code in controller
Rails::Generators.invoke("ead_document", [@document_type.table_name.classify, "--document_type_id=#{@document_type.id}"])
is the same as this in console
rails generate ead_document TechnicalOpinion --document_type_id=1
In case you want to use it outside a controller, you may also want to require it explicitely:
require 'rails/generators'
Related Topics
Watir. Scroll to a Certain Point of the Page
How to Save Dates in Local Timezone to Db with Rails3
Rails 4 - Syntax Error, Unexpected Tidentifier, Expecting End-Of-Input
Restful File Uploads with Carrierwave
Gem Not Found in Ruby Cron Job in Rvm Env
Setting Up Facets in Elasticsearch with Searchkick Gem in Rails 4.1
Convert Array to Hash While Preserving Array Index Values in Ruby
What Does the Regular Expression [\W-] Mean
Pry Not Stopping When Called from a Ruby Script That Reads from Stdin
Why Is This Permissions Error Occurring with Mod_Passenger.So
Call Task More Than Once in Rails 3 Generator
Url_For of a Custom Restful Resource (Composite Key; Not Just Id)
Ruby Model Output Id as Object Oid
Does C1 Code Coverage Analysis Exist for Ruby
Rspec and Shoulda - Complementary or Alternatives
In Ruby, How to I Control the Order in Which Test::Unit Tests Are Run