2008-09-25 8 views

Respuesta

87

Ninguna de estas soluciones considera una constante con varios módulos principales. Por ejemplo:

A::B::C 

A partir de Rails 3.2.x puede simplemente:

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

A partir de Rails 3.1.x se puede:

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

Esto se debe a #demodulize es lo contrario de #deconstantize:

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

Si realmente necesita hacer esto manualmente, intente esto:

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

Esta debería ser la respuesta aceptada. – pdoherty926

+0

Esta pregunta se escribió antes de Rails 3, y los módulos no fueron realmente compatibles. ¡Respuesta aceptada actualizada para reflejar más versiones actuales! – Steropes

+1

demodulizar fue la respuesta clave – Donato

21

Esto debe hacerlo:

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

o u también puede utilizar ** ** self.class.name.demodulize para ese propósito. – TiSer

+3

no, no se puede, en realidad demodulizar no devuelve el nombre de clase sin espacios de nombres – Fivell

+2

Como Jason Harrelson señaló, esto no toma en cuenta múltiples módulos principales. – roychri

1

No creo que hay una manera más limpia , y he visto esto en otro lugar

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

Esto funcionaría si el controlador tenía un nombre de módulo, pero devolvería el nombre del controlador si no lo hiciera.

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

Sin embargo, si cambiamos esto un poco a:

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 

se puede determinar si la clase tiene un nombre de módulo o no y devuelve otra cosa que no sea el nombre de la clase que se puede probar para.

2

Sé que este es un hilo viejo, pero me encontré con la necesidad de tener una navegación separada según el espacio de nombres del controlador. La solución que se me ocurrió fue esto en mi diseño de la aplicación:

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

que parece un poco complicado, pero básicamente hace lo siguiente - que toma el nombre de la clase controlador, que serían, por ejemplo, "Personas" para un país que no controlador de espacio de nombres, y "Admin :: Users" para uno de espacio de nombres. Usando el método de cadena [] con una expresión regular que devuelve algo antes de dos puntos, o nada si no hay nada. A continuación, cambia eso a minúsculas (la "prueba" está allí en caso de que no haya espacio de nombres y se devuelve nil). Esto nos deja con el espacio de nombres o nil. Entonces simplemente hace que la parcial con o sin el espacio de nombres, por ejemplo no espacio de nombres:

app/views/_nav.html.erb 

o en el administrador de espacio de nombres:

app/views/admin/_nav.html.erb 

Por supuesto, estos parciales tiene que existir para cada espacio de nombres de otro modo un error ocurre. Ahora la navegación para cada espacio de nombres aparecerá para cada controlador sin tener que cambiar ningún controlador o vista.

1

I recomiende gsub en lugar de split. Es más efectivo que split dado que no necesita ningún otro nombre de módulo.

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)

o

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

14

Para el caso simple, que puede utilizar:

self.class.parent 
+0

¿Está disponible solo en Rubies recientes? No puedo creer que haya tantas respuestas con "magia oscura" y ninguna hizo referencia a este método hasta 2015 –

1

Con muchos sub-módulos:

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

Ejemplo: Foo::Bar::BazController =>Foo::Bar