namespace - ¿Cómo se encuentra el nombre/nombre del módulo programáticamente en Ruby on Rails?
routes rails examples (9)
¿Cómo puedo encontrar el nombre del espacio de nombres o módulo ''Foo'' en el filtro a continuación?
class ApplicationController < ActionController::Base
def get_module_name
@module_name = ???
end
end
class Foo::BarController < ApplicationController
before_filter :get_module_name
end
Recomiendo gsub
lugar de split
. Es más efectivo 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
Esto debería hacerlo:
def get_module_name
@module_name = self.class.to_s.split("::").first
end
Esto funcionaría si el controlador tuviera 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
Puede determinar si la clase tiene un nombre de módulo o no y devolver algo más que el nombre de la clase que puede probar.
No creo que haya una manera más limpia , y lo he visto en otro lado
class ApplicationController < ActionController::Base
def get_module_name
@module_name = self.class.name.split("::").first
end
end
Sé que este es un hilo antiguo, pero descubrí la necesidad de tener una navegación separada según el espacio de nombres del controlador. La solución que surgió fue esta en el diseño de mi aplicación:
<%= render "#{controller.class.name[/^(/w*)::/w*$/, 1].try(:downcase)}/nav" %>
Lo que parece un poco complicado, pero básicamente hace lo siguiente: toma el nombre de la clase del controlador, que sería por ejemplo "Gente" para un controlador sin nombre de espacio, y "Administrador :: Usuarios" para un espacio con nombre. 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. Luego simplemente representa el parcial con o sin el espacio de nombres, por ejemplo, sin espacio de nombres:
app/views/_nav.html.erb
o en el espacio de nombres de administración:
app/views/admin/_nav.html.erb
Por supuesto, estos parciales deben existir para cada espacio de nombres, de lo contrario, se produce un error. Ahora la navegación para cada espacio de nombres aparecerá para cada controlador sin tener que cambiar ningún controlador o vista.
Ninguna de estas soluciones considera una constante con múltiples módulos principales. Por ejemplo:
A::B::C
A partir de Rails 3.2.x puedes simplemente:
"A::B::C".deconstantize #=> "A::B"
A partir de Rails 3.1.x puedes:
constant_name = "A::B::C"
constant_name.gsub( "::#{constant_name.demodulize}", '''' )
Esto es porque #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]
my_class.name.underscore.split(''/'').slice(0..-2)
o
my_class.name.split(''::'').slice(0..-2)
Para el caso simple, puedes usar:
self.class.parent
Con muchos submódulos:
module ApplicationHelper
def namespace
controller.class.name.gsub(/(::)?/w+Controller$/, '''')
end
end
Ejemplo: Foo::Bar::BazController
=> Foo::Bar