ruby / rails:扩展或包含其他模块

我将模块分开,以便更容易阅读和搜索

lib features - running.rb - walking.rb features.rb 

他们有

 # lib/features/running.rb module Features::Running extend ActiveSupport::Concern module ClassMethods def can_run ... end end end 

另一个是:

 # lib/features/walking.rb module Features::Walking extend ActiveSupport::Concern module ClassMethods def can_walk ... end end end 

总有一天我可能会有这么多。

我的问题是当我想在模型中添加它们时,我需要

 # Sample model class Man < ActiveRecord::Base # Include features modules include Features::Walking include Features::Running # Define what man can do can_walk can_run end 

我想知道是否有办法创建另一个模块并包含所有模块。 就像是:

 # lib/features.rb module Features extend ActiveSupport::Concern extend Features::Walking extend Features::Running end 

所以我只需要添加

 # Sample model class Man < ActiveRecord::Base # Include features modules include Features # Define what man can do can_walk can_run end 

或者我应该怎么做呢?

编辑 – 解决方案

我现在基于@Chris解决方案获得了修复。 我有这样的事情:

 module Features FEATURES = %w(running walking) # include Features::Running FEATURES.each do |feature| send :include, "Features::#{feature.camelize}".constantize end module ClassMethods # include Features::Running::ClassMethods FEATURES.each do |feature| send :include, "Features::#{feature.camelize}::ClassMethods".constantize end end def self.included(base) base.send :extend, ClassMethods end end 

我的其他function模块现在是:

 # lib/features/running.rb module Features::Running module ClassMethods def can_run ... end end end # lib/features/walking.rb module Features::Walking module ClassMethods def can_walk ... end end end 

编辑 – 更新解决方案

 module Features FEATURES = [Running, Walking] # include Features::Running FEATURES.each do |feature| send :include, feature end module ClassMethods # include Features::Running::ClassMethods FEATURES.each do |feature| send :include, feature::ClassMethods end end def self.included(base) base.send :extend, ClassMethods end end 

您可以; 您可能遇到的问题是ActiveSupport::Concern自动将ClassMethods的方法ClassMethods到目标类,而不是将多个ClassMethods子模块合并为一个。 不幸的是,由于Ruby的循环包含防止代码,这有点难以自动完成,但实际上你可以在没有AS :: Concern的情况下手动完成。

 module Foo def foo end module ClassMethods def cfoo end end end module Baz def baz end module ClassMethods def cbaz end end end module Bar include Baz def bar end module ClassMethods include Baz::ClassMethods def cbar end end end module Stuff include Foo include Bar module ClassMethods include Foo::ClassMethods include Bar::ClassMethods end end class Final include Stuff extend Stuff::ClassMethods end 

这有点冗长,但是您可以根据需要编写碎片,但是必须小心始终包含父模块,然后将ClassMethods包含到相应的ClassMethods子模块中。