How to find namespace / module name in Ruby on Rails?

How to find the namespace name or module "Foo" in the filter below?

class ApplicationController < ActionController::Base def get_module_name @module_name = ??? end end class Foo::BarController < ApplicationController before_filter :get_module_name end 
+47
ruby namespaces ruby-on-rails
Sep 25 '08 at 13:34
source share
9 answers

None of these solutions consider a constant with multiple parent modules. For example:

 A::B::C 

With Rails 3.2.x, you can simply:

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

In Rails 3.1.x, you can:

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

This is because #demodulize is the opposite of #deconstantize:

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

If you really need to do this manually, try the following:

 constant_name = "A::B::C" constant_name.split( '::' )[0,constant_name.split( '::' ).length-1] 
+85
Jan 03 '13 at 19:20
source share

This should do it:

  def get_module_name @module_name = self.class.to_s.split("::").first end 
+21
Sep 25 '08 at 13:40
source share

For a simple case, you can use:

 self.class.parent 
+12
Jan 09 '15 at 9:01
source share

This will work if the controller had a module name, but it will return the controller name if it is not.

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

However, if we change this a bit:

 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 

You can determine if the class has a module name or not, and return something other than the class name, which you can check.

+6
Sep 25 '08 at 14:04
source share

I know this is an old thread, but I just ran into the need to have separate navigation depending on the namespace of the controller. The solution I came up with was in my application layout:

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

Which looks a bit more complicated, but basically does the following: for the controller name, the class name is used, which will be, for example, "People" for the controller without names, and "Admin :: Users" for the namespace. Using the [] string method with a regex that returns something before two colons, or nil if not. Then he changes it to lowercase ("try" is where there is no namespace and nil is returned). This leaves us with either a namespace or nil. Then it simply displays partial with or without a namespace, for example without a namespace:

 app/views/_nav.html.erb 

or in the admin namespace:

 app/views/admin/_nav.html.erb 

Of course, these partial must exist for each namespace, otherwise an error occurs. Now for each namespace navigation will be displayed for each controller without the need to change any controller or view.

+2
May 6 '10 at 8:12 a.m.
source share

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

or

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

+2
Apr 04 '14 at 16:35
source share

I don’t think there is a cleaner way, and I saw it somewhere else.

 class ApplicationController < ActionController::Base def get_module_name @module_name = self.class.name.split("::").first end end 
+1
Sep 25 '08 at 13:42
source share

I recommend gsub instead of split . This is more efficient than split , given that you do not need a different module name.

 class ApplicationController < ActionController::Base def get_module_name @module_name = self.class.to_s.gsub(/::.*/, '') end end 
+1
Jul 23 '13 at 2:14
source share

With many submodules:

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

Example: Foo::Bar::BazController => Foo::Bar

+1
Nov 24 '15 at 11:35
source share



All Articles