Rails 3:获取当前命名空间?

arn*_*lja 31 namespaces ruby-on-rails actioncontroller ruby-on-rails-3

使用方法:layout_for_namespace我设置我的应用程序的布局取决于我是在前端还是后端,因为后端使用命名空间"admin".

我找不到一个很好的方法来找出我是哪个命名空间,我找到的唯一方法是从params [:controller]解析字符串.当然这很容易,似乎是安全的,并且运行良好.但我只是想知道是否有更好的,准备好的方法来做到这一点.有人知道吗?

目前我只使用以下方法:

def is_backend_namespace?
  params[:controller].index("admin/") == 0
end
Run Code Online (Sandbox Code Playgroud)

提前致谢

阿恩

小智 41

您可以使用:

self.class.parent == Admin
Run Code Online (Sandbox Code Playgroud)

  • 正如许多人所指出的,这对于具有多级命名空间的类不起作用.但是,如果你只是检查你是否在这样的命名空间(就像OP类型的那样),那么你可以使用`controller.class.parents.include?(Admin)`并获得类似的东西而不必求助于字符串解析 (9认同)

Boo*_*age 27

在控制器外部(例如在视图中),使用controller.class.name.您可以将其转换为这样的辅助方法:

module ApplicationHelper
  def admin?
    controller.class.name.split("::").first=="Admin"
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 也可以在视图中使用controller.class.parent.name (2认同)
  • 看起来像脏代码...我认为使用class.parent更清楚 (2认同)

Ken*_*enB 18

在控制器和视图中,您可以解析controller_path,例如:

namespace = controller_path.split('/').first
Run Code Online (Sandbox Code Playgroud)


joh*_*ley 11

不是更优雅,但它使用类而不是params哈希.如果没有一些解析,我不知道有一种"准备好"的方法来做到这一点.

self.class.to_s.split("::").first=="Admin"
Run Code Online (Sandbox Code Playgroud)

  • 更简单的`controller.class.name.start_with?('Admin')`. (2认同)

Jas*_*son 11

这些解决方案都没有考虑具有多个父模块的常量.例如:

A::B::C
Run Code Online (Sandbox Code Playgroud)

从Rails 3.2.x开始,您可以简单地:

"A::B::C".deconstantize #=> "A::B"
Run Code Online (Sandbox Code Playgroud)

从Rails 3.1.x开始,您可以:

constant_name = "A::B::C"
constant_name.gsub( "::#{constant_name.demodulize}", '' )
Run Code Online (Sandbox Code Playgroud)

这是因为#demodulize与#deconstantize相反:

"A::B::C".demodulize #=> "C"
Run Code Online (Sandbox Code Playgroud)

如果您确实需要手动执行此操作,请尝试以下操作:

constant_name = "A::B::C"
constant_name.split( '::' )[0,constant_name.split( '::' ).length-1]
Run Code Online (Sandbox Code Playgroud)


小智 7

在应用程序控制器中设置命名空

path = self.controller_path.split('/')
@namespace = path.second ? path.first : nil
Run Code Online (Sandbox Code Playgroud)

  • 这样可以避免三元组:@namespace =(path.first if path.second) (2认同)

sta*_*xim 6

Rails 6 中,控制器类似乎没有namespace方法。

看起来最干净并且对我有用的解决方案是: controller.class.module_parent

具体来说,如果你的命名空间是 Admin:: 并且你想要“admin”,你会这样做: controller.class.module_parent.to_s.downcase