62

以下のフィルターで名前空間またはモジュール「Foo」の名前を見つけるにはどうすればよいですか?

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


class Foo::BarController < ApplicationController
  before_filter :get_module_name
end
4

11 に答える 11

103

これらのソリューションはいずれも、複数の親モジュールを持つ定数を考慮していません。例えば:

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]
于 2013-01-03T19:20:33.350 に答える
21

これはそれを行う必要があります:

  def get_module_name
    @module_name = self.class.to_s.split("::").first
  end
于 2008-09-25T13:40:09.450 に答える
6

これは、コントローラーにモジュール名がある場合は機能しますが、モジュール名がない場合はコントローラー名を返します。

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

クラスにモジュール名があるかどうかを判断し、テストできるクラス名以外の何かを返すことができます。

于 2008-09-25T14:04:19.533 に答える
2

これが古いスレッドであることは知っていますが、コントローラーの名前空間に応じて個別のナビゲーションが必要になることに気づきました。私が思いついた解決策は、私のアプリケーションレイアウトでこれでした:

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

これは少し複雑に見えますが、基本的に次のことを行います。たとえば、名前空間のないコントローラーの場合は「People」、名前空間のコントローラーの場合は「Admin::Users」などのコントローラークラス名を使用します。2つのコロンの前に何かを返す正規表現で[]文字列メソッドを使用するか、何もない場合はnilを使用します。次に、それを小文字に変更します(名前空間がなく、nilが返される場合は、「try」があります)。これにより、名前空間またはnilが残ります。次に、名前空間の有無にかかわらず、部分を単純にレンダリングします。たとえば、名前空間はありません。

app/views/_nav.html.erb

またはadmin名前空間:

app/views/admin/_nav.html.erb

もちろん、これらのパーシャルは名前空間ごとに存在する必要があります。存在しない場合、エラーが発生します。これで、コントローラーやビューを変更しなくても、各名前空間のナビゲーションがすべてのコントローラーに表示されます。

于 2010-05-06T08:12:31.833 に答える
1

よりクリーンな方法はないと思います。これは別の場所で見たことがあります

class ApplicationController < ActionController::Base
  def get_module_name
    @module_name = self.class.name.split("::").first
  end
end
于 2008-09-25T13:42:32.940 に答える
1

gsubの代わりにお勧めしsplitます。split他のモジュール名が必要ないことを考えると、より効果的です。

class ApplicationController < ActionController::Base
  def get_module_name
    @module_name = self.class.to_s.gsub(/::.*/, '')
  end
end
于 2013-07-23T02:14:24.533 に答える
1

多くのサブモジュールを使用:

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

例: Foo::Bar::BazController=>Foo::Bar

于 2015-11-24T11:35:29.070 に答える