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

StackOverflow https://stackoverflow.com/questions/133357

  •  02-07-2019
  •  | 
  •  

문제

아래 필터에서 네임 스페이스 또는 모듈 '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]

다른 팁

이렇게해야합니다.

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

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

self.class.parent

컨트롤러가 모듈 이름을 가지고 있지만 컨트롤러 이름을 반환하지 않으면 작동하지 않습니다.

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

클래스에 모듈 이름이 있는지 여부를 결정하고 테스트 할 수있는 클래스 이름 이외의 다른 것을 반환 할 수 있습니다.

나는 이것이 오래된 스레드라는 것을 알고 있지만 컨트롤러의 네임 스페이스에 따라 별도의 탐색이 필요했습니다. 제가 생각해 낸 해결책은 내 응용 프로그램 레이아웃에서 이것입니다.

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

약간 복잡해 보이지만 기본적으로 다음을 수행합니다. 컨트롤러 클래스 이름을 사용합니다. 예를 들어 이름이없는 컨트롤러의 경우 "사람"과 네임 스패닝 된 컨트롤러의 경우 "admin :: 사용자"입니다. [] 문자열 메소드를 사용하여 두 개의 콜론 이전에 무엇이든 반환하는 정규 표현 또는 아무것도없는 경우 NIL을 사용합니다. 그런 다음 소문자로 변경합니다 (네임 스페이스가없고 NIL이 반환되는 경우 "시도"가 있습니다). 그런 다음 네임 스페이스 또는 NIL을 남겨 둡니다. 그런 다음 네임 스페이스가 있거나없는 부분을 예를 들어 네임 스페이스가없는 부분을 부분적으로 렌더링합니다.

app/views/_nav.html.erb

또는 관리자 네임 스페이스에서 :

app/views/admin/_nav.html.erb

물론 이러한 부분은 각 네임 스페이스마다 존재해야합니다. 그렇지 않으면 오류가 발생합니다. 이제 각 네임 스페이스의 내비게이션은 컨트롤러 나보기를 변경하지 않고 모든 컨트롤러에 대해 나타납니다.

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

또는

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

나는 거기에 있다고 생각하지 않습니다 청소기 길, 나는 이것을 다른 곳에서 보았다

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

추천합니다 gsub 대신에 split. 더 효과적입니다 split 다른 모듈 이름이 필요하지 않다는 점에서.

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

많은 하위 모듈로 :

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

예시: Foo::Bar::BazController => Foo::Bar

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top