Comment convertir un nom de classe Ruby en symbole délimité par un trait de soulignement?


95

Comment puis-je transformer par programme un nom de classe,, FooBaren symbole :foo_bar,? par exemple quelque chose comme ça, mais qui gère correctement le cas de chameau?

FooBar.to_s.downcase.to_sym

Réponses:


141

Rails est livré avec une méthode appelée underscorequi vous permettra de transformer des chaînes CamelCased en chaînes underscore_separated. Vous pourrez donc peut-être faire ceci:

FooBar.name.underscore.to_sym

Mais vous devrez installer ActiveSupport juste pour faire cela, comme le dit ipsum.

Si vous ne souhaitez pas installer ActiveSupport juste pour cela, vous pouvez singe-patch underscoreen Stringvous - même (la fonction underscore est définie dans ActiveSupport :: Inflector ):

class String
  def underscore
    word = self.dup
    word.gsub!(/::/, '/')
    word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
    word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
    word.tr!("-", "_")
    word.downcase!
    word
  end
end

1
Merci. J'avais peur que ce soit une extension Rails. :) Pas de soucis, car j'utilise actuellement Rails.
Josh Glover

2
Ensuite, vous devriez avoir étiqueté votre question en conséquence. Ici, laissez-moi le faire pour vous ...
kikito

5
Non, pas ActiveRecord. ActiveSupport.
Rein Henrichs

En effet, laissez-moi le changer
kikito

2
comment faire l'inverse?
user1406062

72

Rails 4 .model_name

Dans Rails 4, il renvoie un ActiveModel::Nameobjet qui contient de nombreux attributs plus "sémantiques" utiles tels que:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

FooBar.model_name.human
#=> "Foo bar"

Vous devriez donc en utiliser un s'il correspond à la signification souhaitée, ce qui est probablement le cas. Avantages:

  • plus facile à comprendre votre code
  • votre application fonctionnera toujours même dans le cas (peu probable) où Rails décide de modifier une convention de dénomination.

BTW, humana l'avantage d'être conscient I18N.


model_namefonctionne également pour les objets par exemple. Ex: foo_bar.model_name. Si vous voulez que la liste complète soit écrite foo_bar.model_name.inspectdans la console des rails ou votre débogueur
ivanxuu

et je cherchais le contraire / inverse, classify, modelizene semble pas fonctionner.
Pysis le

7

first: gem install activesupport

require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym

FooBar.to_s.underscore.to_symCela devrait être , puisque j'essaie de convertir une classe (qui est une constante) en un symbole, que je peux ensuite transmettre à Factory Girl . :)
Josh Glover

2

Voici ce que j'ai fait:

module MyModule
  module ClassMethods
    def class_to_sym  
      name_without_namespace = name.split("::").last
      name_without_namespace.gsub(/([^\^])([A-Z])/,'\1_\2').downcase.to_sym
    end
  end

  def self.included(base)
    base.extend(ClassMethods)
  end
end

class ThisIsMyClass
  include MyModule
end 

ThisIsMyClass.class_to_sym #:this_is_my_class

3
ActiveSupport a String#demodulizequi supprimera la pièce avant ::.
amoebe le

@amoebe - merci pour l'info. Cela dépend de ce sur quoi vous travaillez - vous ne travaillez peut-être pas sur une application de rails (ou même une application Web).
Louis Sayers
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.