2008-09-25 44 views

回答

87

这些解决方案都没有考虑多个父模块的常量。例如:

A::B::C 

,你可以简单的Rails的3.2.x中:

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

铁轨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] 
21

这应做到:

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

或u也可以使用** ** self.class.name.demodulize用于该目的。 – TiSer 2012-07-24 10:15:26

+3

不,你不能,实际上demodulize确实返回没有命名空间的类名称 – Fivell 2012-12-12 13:39:00

+2

正如Jason Harrelson指出的那样,这没有考虑多个父模块。 – roychri 2013-07-25 20:05:56

1

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

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

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

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 

您可以确定类有一个模块名称或不并返回其他别的东西比类的名字,你可以测试对于。

2

我知道这是一个旧的线程,但我只是碰到需要单独导航取决于控制器的命名空间。我想出了解决的办法是这在我的应用程序布局:

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

这看起来有点复杂,但基本上没有下 - 它需要在控制器类名,这将是,例如,对“人”非命名空间控制器和命名空间的“Admin :: Users”。使用带有正则表达式的[]字符串方法,该方法在两个冒号前返回任何内容,如果没有任何内容,则为零。然后它将其改为小写(如果没有命名空间并且返回nil,那么“try”就在那里)。这会让我们留下命名空间或零。然后,它简单地使该部分的有或无的命名空间,例如不名称空间:

app/views/_nav.html.erb 

或在管理名字空间:

app/views/admin/_nav.html.erb 

当然这些泛音具有每个命名空间否则错误存在发生。现在每个控制器都会显示每个命名空间的导航,而无需更改任何控制器或视图。

1

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

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

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

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

14

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

self.class.parent 
1

随着许多子模块:

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

示例:Foo::Bar::BazController =>Foo::Bar

相关问题