如何在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