62 votes

Comment trouvez-vous l'espace de noms/nom du module par programmation en Ruby on Rails?

Comment puis-je trouver le nom de l'espace de noms ou d'un module " Foo " dans le filtre ci-dessous?

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


class Foo::BarController < ApplicationController
  before_filter :get_module_name
end

103voto

Jason Harrelson Points 436

Aucune de ces solutions envisager une constante avec plusieurs parents modules. Par exemple:

A::B::C

Comme des Rails 3.2.x, vous pouvez tout simplement:

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

Comme de Rails 3.1.x, vous pouvez:

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

C'est parce que #demodulize est à l'opposé de #deconstantize:

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

Si vous avez vraiment besoin de le faire manuellement, essayez ceci:

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

21voto

Daniel Lucraft Points 3323

Cela devrait le faire:

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

6voto

Steropes Points 474

Cela ne peut fonctionner que si le contrôleur avait un nom de module, mais serait de retour le nom du contrôleur si elle n'a pas.

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

Toutefois, si nous le changeons un peu de:

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

Vous pouvez déterminer si la classe a un nom de module ou pas et de retourner quelque chose d'autre que le nom de la classe que vous pouvez tester.

2voto

sandstrom Points 2420

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

ou

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

2voto

fishwebby Points 1971

Je sais que c'est un vieux thread, mais je viens de tomber sur la nécessité de séparer la navigation en fonction de l'espace de noms du contrôleur. La solution je suis venu avec était-ce dans mon application de mise en page:

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

Qui ressemble un peu compliqué mais en gros la suivante - il prend le nom de la classe contrôleur, qui serait par exemple "les Gens" pour un non-préfixée contrôleur, et "Admin::les Utilisateurs" pour l'un des espaces de l'un. À l'aide de [la] méthode de chaîne avec une expression régulière qui renvoie rien avant deux points, ou nil si il n'y a rien. Il change alors que pour les minuscules (les "essayer" est-il dans le cas où il n'y a pas d'espace de noms et le nil est retourné). Ensuite, cela nous laisse avec l'espace de noms ou nul. Ensuite, il suffit rend l'partielle avec ou sans l'espace de noms, par exemple, aucun espace de noms:

app/views/_nav.html.erb

ou dans l'admin de l'espace de noms:

app/views/admin/_nav.html.erb

Bien sûr, ces partiels doivent exister pour chaque espace de noms, sinon une erreur se produit. Maintenant, la navigation pour chaque espace de noms apparaît pour chaque contrôleur sans avoir à modifier tout ou contrôleur de vue.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X