Frage

Wie finde ich den Namen des Namespace oder Modul ‚Foo‘ in den unten stehenden Filter?

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


class Foo::BarController < ApplicationController
  before_filter :get_module_name
end
War es hilfreich?

Lösung

Keine dieser Lösungen betrachtet eine Konstante mit mehreren übergeordneten Modulen. Zum Beispiel:

A::B::C

Ab Rails 3.2.x können Sie einfach:

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

Ab Rails 3.1.x können Sie:

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

Das ist, weil #demodulize das Gegenteil von #deconstantize ist:

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

Wenn Sie wirklich dies manuell tun müssen, um, versuchen Sie dies:

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

Andere Tipps

Das sollte es tun:

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

Für den einfachen Fall, können Sie verwenden:

self.class.parent

Das würde funktionieren, wenn der Controller einen Modulnamen hat, aber würde den Controller-Namen zurück, wenn es nicht.

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

Wenn wir jedoch diese ändern sich ein wenig zu:

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

Sie können bestimmen, ob die Klasse einen Modulnamen hat oder nicht und das Rück etwas anderes als die Klassennamen, die Sie testen können.

Ich weiß, das ist ein alter Thread, aber ich kam gerade über die Notwendigkeit, separate Navigation haben, je nach dem Namensraum des Controllers. Die Lösung kam ich mit war dies in meiner Anwendung Layout:

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

, die ein bisschen sieht kompliziert, aber im Grunde hat den folgend - es nimmt den Controller Klassennamen, die zum Beispiel „Menschen“ für einen nicht-Namespace-Controller sein würden, und „Admin :: Users“ für einen Namensraum ein. Mit der [] String-Methode mit einem regulären Ausdruck, der etwas vor zwei Doppelpunkte zurückgibt, oder null, wenn es nichts ist. Es ändert sich dann, dass in Kleinbuchstaben (die „versuchen“ gibt es im Fall gibt es keinen Namensraum und nil zurückgegeben). Diese dann lassen uns entweder mit dem Namensraum oder gleich Null. Dann macht es einfach, die teilweise mit oder ohne Namensraum, beispielsweise keinen Namensraum:

app/views/_nav.html.erb

oder im Admin-Namespace:

app/views/admin/_nav.html.erb

Natürlich haben diese partials für jeden Namespace existieren sonst ein Fehler auftritt. Nun ist die Navigation für jeden Namespace wird für jeden Controller angezeigt werden, ohne eine Steuerung oder Ansicht zu ändern.

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

oder

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

Ich glaube nicht, gibt es eine Reiniger Art und Weise, und ich habe diese woanders gesehen

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

Ich empfehle statt gsub split. Es ist effektiver, dass split gegeben, dass Sie keine anderen Modulnamen benötigen.

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

Bei vielen Untermodule:

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

Beispiel: Foo::Bar::BazController => Foo::Bar

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top