root_path rails namespace examples and ruby-on-rails ruby namespaces

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