Comment trouvez-vous le nom de l'espace de nom / du module par programme dans Ruby on Rails?

StackOverflow https://stackoverflow.com/questions/133357

  •  02-07-2019
  •  | 
  •  

Question

Comment trouver le nom de l'espace de noms ou du 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
Était-ce utile?

La solution

Aucune de ces solutions ne considère une constante avec plusieurs modules parents. Par exemple:

A::B::C

À partir de Rails 3.2.x, vous pouvez simplement:

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

À partir 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]

Autres conseils

Cela devrait le faire:

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

Pour le cas simple, vous pouvez utiliser:

self.class.parent

Cela fonctionnerait si le contrôleur avait un nom de module, mais renverrait le nom du contrôleur s'il ne le possédait pas.

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

Cependant, si nous modifions cela un peu en:

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 non et renvoyer autre chose que le nom de la classe que vous pouvez tester.

Je sais que c’est un vieux fil de discussion, mais j’ai juste eu le besoin d’avoir une navigation séparée en fonction de l’espace de noms du contrôleur. La solution que j'ai trouvée est la suivante:

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

Ce qui semble un peu compliqué, mais fait essentiellement ce qui suit: il prend le nom de la classe du contrôleur, qui serait par exemple "Personnes". pour un contrôleur non-namespaced, et " Admin :: Users " pour un nom. Utilisation de la méthode de chaîne [] avec une expression régulière qui retourne tout ce qui précède les deux points, ou nil s'il n'y a rien. Il change ensuite cette valeur en minuscule (l'option "essayer" existe dans le cas où il n'y a pas d'espace de nom et que nil est renvoyé). Cela nous laisse alors avec l'espace de noms ou nil. Ensuite, il rend simplement le partiel avec ou sans l'espace de nom, par exemple, aucun espace de nom:

app/views/_nav.html.erb

ou dans l'espace de noms administrateur:

app/views/admin/_nav.html.erb

Bien entendu, 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 à changer de contrôleur ou de vue.

mon_classe.nom.underscore.split ('/'). slice (0 ..- 2)

ou

mon_classe.nom.split ('::'). slice (0 ..- 2)

Je ne pense pas qu'il existe un moyen plus propre , et je l'ai déjà vu ailleurs

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

Je recommande gsub au lieu de split . Il est plus efficace que split , étant donné que vous n'avez besoin d'aucun autre nom de module.

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

Avec de nombreux sous-modules:

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

Exemple: Foo :: Bar :: BazController = > Foo :: Bar

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top