如何在Ruby on Rails中以编程方式查找名称空间/模块名称?

如何在下面的filter中find名称空间或模块“Foo”的名称?

class ApplicationController < ActionController::Base def get_module_name @module_name = ??? end end class Foo::BarController < ApplicationController before_filter :get_module_name end 

这些解决scheme都不考虑多个父模块的常量。 例如:

 A::B::C 

从Rails 3.2.x开始,你可以简单地:

 "A::B::C".deconstantize #=> "A::B" 

从Rails 3.1.x开始,你可以:

 constant_name = "A::B::C" constant_name.gsub( "::#{constant_name.demodulize}", '' ) 

这是因为#demodulize和#deconstantize是相反的:

 "A::B::C".demodulize #=> "C" 

如果你真的需要手动做这个,试试这个:

 constant_name = "A::B::C" constant_name.split( '::' )[0,constant_name.split( '::' ).length-1] 

这应该做到这一点:

  def get_module_name @module_name = self.class.to_s.split("::").first end 

对于简单的情况,您可以使用:

 self.class.parent 

如果控制器有一个模块名称,这将工作,但如果没有,则会返回控制器名称。

 class ApplicationController < ActionController::Base def get_module_name @module_name = self.class.name.split("::").first end end 

但是,如果我们稍微改变这一点:

 class ApplicatioNController < ActionController::Base def get_module_name my_class_name = self.class.name if my_class_name.index("::").nil? then @module_name = nil else @module_name = my_class_name.split("::").first end end end 

您可以确定类是否有模块名称,并返回除您可以testing的类名以外的其他内容。

我知道这是一个古老的线程,但我只是遇到需要有单独的导航取决于控制器的命名空间。 我提出的解决scheme是在我的应用程序布局中:

 <%= render "#{controller.class.name[/^(\w*)::\w*$/, 1].try(:downcase)}/nav" %> 

这看起来有点复杂,但基本上做了以下事情 – 它采用控制器类的名称,例如非人名空间控制器的“People”,以及名称空间控制器的“Admin :: Users”。 使用带有正则expression式的[]string方法,该方法在两个冒号前面返回任何内容,如果没有,则为零。 然后将其更改为小写(如果没有名称空间,则返回“try”,否则返回nil)。 这然后留给我们的名字空间或零。 然后它只是简单地渲染带或不带名字空间的部分,例如没有名字空间:

 app/views/_nav.html.erb 

或在pipe理员名称空间中:

 app/views/admin/_nav.html.erb 

当然,这些部分必须存在于每个命名空间,否则会发生错误。 现在每个控制器都会显示每个命名空间的导航,而不必更改任何控制器或视图。

my_class.name.underscore.split('/').slice(0..-2)

要么

my_class.name.split('::').slice(0..-2)

我不认为有一个更清洁的方式,我已经看到了这个地方

 class ApplicationController < ActionController::Base def get_module_name @module_name = self.class.name.split("::").first end end 

我推荐gsub而不是split 。 考虑到您不需要任何其他模块名称, split更有效。

 class ApplicationController < ActionController::Base def get_module_name @module_name = self.class.to_s.gsub(/::.*/, '') end end 

有了许多子模块:

 module ApplicationHelper def namespace controller.class.name.gsub(/(::)?\w+Controller$/, '') end end 

例如: Foo::Bar::BazController => Foo::Bar