Rails Gem:为给定的命名空间运行所有生成器

时间:2013-04-05 20:32:09

标签: ruby-on-rails ruby ruby-on-rails-3 gem

我正在开发一个带有多个子模块的宝石核心,每个模块都有自己的宝石。作为开发人员,您将能够安装核心和任何其他宝石。如何创建一个rake任务或生成器,以便在主gem命名空间下为所有已安装的gem运行生成器。

例如,如果我的宝石名为 admin

module Admin
  module Generators
    class InstallGenerator < Rails::Generators::Base
    end
  end
end

我有一个子宝石的另一个发生器:

module Admin
  module Generators
    class PostsGenerator < Rails::Generators::Base
    end
  end
end

还有一个:

module Admin
  module Generators
    class TagslGenerator < Rails::Generators::Base
    end
  end
end

最多可以安装10个宝石。而不是铁路管理员:...安装每一个,我想创建一个运行所有任务的rake任务或生成器。

提前致谢!

2 个答案:

答案 0 :(得分:1)

首先查看以下问题和答案。

Find classes available in a Module

所以你要做的就是访问

Admin::Generators.constants.each do |c| 
   c = Admin::Generators.const_get(c)
   if c < Rails::Generators::Base
     c.new.run(your_args)
   end
end

唯一的问题是我从未调用过这样的生成器,所以它可能比c.new.run多一点,但我认为应该这样做。

答案 1 :(得分:1)

在“管理”模块下保留“AllGenerator”类。生成器必须执行以下操作:

  1. 对于作为生成器类的命名空间下的每个类,
  2. 从classname获取命名空间。
  3. 使用命名空间调用invoke method
  4. 这样的事情:

    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

    这样,运行rails g admin:all将直接在Admin::Generators下运行所有​​其他生成器。