Как программно найти имя пространства имен / модуля в Ruby on Rails? - PullRequest
53 голосов
/ 25 сентября 2008

Как найти имя пространства имен или модуля 'Foo' в фильтре ниже?

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


class Foo::BarController < ApplicationController
  before_filter :get_module_name
end

Ответы [ 9 ]

96 голосов
/ 03 января 2013

Ни одно из этих решений не рассматривает константу с несколькими родительскими модулями. Например:

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]
22 голосов
/ 25 сентября 2008

Это должно сделать это:

  def get_module_name
    @module_name = self.class.to_s.split("::").first
  end
21 голосов
/ 09 января 2015

Для простого случая, вы можете использовать:

self.class.parent
6 голосов
/ 25 сентября 2008

Это сработало бы, если бы у контроллера было имя модуля, но вернуло бы имя контроллера, если оно не было.

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

Вы можете определить, есть ли у класса имя модуля или нет, и вернуть что-то другое, кроме имени класса, для которого вы можете проверить.

2 голосов
/ 04 апреля 2014

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

или

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

2 голосов
/ 06 мая 2010

Я знаю, что это старый поток, но я только что столкнулся с необходимостью иметь отдельную навигацию в зависимости от пространства имен контроллера. Решение, которое я придумал, заключалось в следующем: «1001»

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

Что выглядит немного сложнее, но в основном делает следующее: для него берется имя класса контроллера, например, «People» для контроллера без пространства имен и «Admin :: Users» для пространства имен. Использование строкового метода [] с регулярным выражением, которое возвращает что-либо до двух двоеточий, или nil, если ничего нет. Затем он меняет это на нижний регистр («try» есть в случае, если нет пространства имен и возвращается nil). Это тогда оставляет нам или пространство имен или ноль. Затем он просто визуализирует частичное с пространством имен или без него, например, без пространства имен:

app/views/_nav.html.erb

или в пространстве имен администратора:

app/views/admin/_nav.html.erb

Конечно, эти частичные значения должны существовать для каждого пространства имен, в противном случае возникает ошибка. Теперь навигация для каждого пространства имен будет отображаться для каждого контроллера без необходимости изменения какого-либо контроллера или представления.

1 голос
/ 23 июля 2013

Я рекомендую gsub вместо split. Это более эффективно, чем split, учитывая, что вам не нужно другое имя модуля.

class ApplicationController < ActionController::Base
  def get_module_name
    @module_name = self.class.to_s.gsub(/::.*/, '')
  end
end
1 голос
/ 25 сентября 2008

Я не думаю, что есть очиститель способ, и я видел это где-то еще

class ApplicationController < ActionController::Base
  def get_module_name
    @module_name = self.class.name.split("::").first
  end
end
0 голосов
/ 24 ноября 2015

Со многими подмодулями:

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

Пример: Foo::Bar::BazController => Foo::Bar

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...