How do you find the namespace/module name programmatically in Ruby on Rails?

Viewed 55644

How do I find the name of the namespace 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
11 Answers

This should do it:

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

For Rails 6.1

self.class.module_parent


Hettomei answer works fine up to Rails 6.0

DEPRECATION WARNING: Module#parent has been renamed to module_parent. parent is deprecated and will be removed in Rails 6.1.

This would work if the controller did have a module name, but would return the controller name if it did not.

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

However, if we change this up a bit to:

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 else other than the class name that you can test for.

No one has mentioned using rpartition?

const_name = 'A::B::C'
namespace, _sep, module_name = const_name.rpartition('::')
# or if you just need the namespace
namespace = const_name.rpartition('::').first

I don't think there is a cleaner way, and I've seen this somewhere else

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