Programing

Ruby on Rails에서 프로그래밍 방식으로 네임 스페이스 / 모듈 이름을 어떻게 찾습니까?

crosscheck 2021. 1. 5. 08:29
반응형

Ruby on Rails에서 프로그래밍 방식으로 네임 스페이스 / 모듈 이름을 어떻게 찾습니까?


아래 필터에서 네임 스페이스 또는 모듈 'Foo'의 이름을 어떻게 찾습니까?

class ApplicationController < ActionController::Base
  def get_module_name
    @module_name = ???
  end
end


class Foo::BarController < ApplicationController
  before_filter :get_module_name
end

이러한 솔루션 중 어느 것도 여러 상위 모듈이있는 상수를 고려하지 않습니다. 예를 들면 :

A::B::C

Rails 3.2.x부터 간단하게 다음을 수행 할 수 있습니다.

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

Rails 3.1.x부터 다음을 수행 할 수 있습니다.

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

이는 #demodulize가 #deconstantize의 반대이기 때문입니다.

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

이 작업을 수동으로 수행해야하는 경우 다음을 시도하십시오.

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

간단한 경우 다음을 사용할 수 있습니다.

self.class.parent

이렇게해야합니다.

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

컨트롤러에 모듈 이름이 있으면 작동하지만 그렇지 않은 경우 컨트롤러 이름을 반환합니다.

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

그러나 이것을 약간 변경하면 다음과 같습니다.

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

클래스에 모듈 이름이 있는지 여부를 확인하고 테스트 할 수있는 클래스 이름이 아닌 다른 것을 반환 할 수 있습니다.


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

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

Which looks a bit complicated but basically does the following - it takes the controller class name, which would be for example "People" for a non-namespaced controller, and "Admin::Users" for a namespaced one. Using the [] string method with a regular expression that returns anything before two colons, or nil if there's nothing. It then changes that to lower case (the "try" is there in case there is no namespace and nil is returned). This then leaves us with either the namespace or nil. Then it simply renders the partial with or without the namespace, for example no namespace:

app/views/_nav.html.erb

or in the admin namespace:

app/views/admin/_nav.html.erb

Of course these partials have to exist for each namespace otherwise an error occurs. Now the navigation for each namespace will appear for every controller without having to change any controller or view.


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

or

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


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

I recommend gsub instead of split. It's more effective that split given that you don't need any other module name.

class ApplicationController < ActionController::Base
  def get_module_name
    @module_name = self.class.to_s.gsub(/::.*/, '')
  end
end

With many sub-modules:

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

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

ReferenceURL : https://stackoverflow.com/questions/133357/how-do-you-find-the-namespace-module-name-programmatically-in-ruby-on-rails

반응형