Pregunta ¿Cómo convierto un nombre de clase Ruby en un símbolo delimitado por guiones bajos?


¿Cómo puedo convertir un nombre de clase mediante programación? FooBar, en un símbolo, :foo_bar? p.ej. algo así, pero que maneja la caja de camello correctamente?

FooBar.to_s.downcase.to_sym

75
2018-04-11 14:03


origen


Respuestas:


Rails viene con un método llamado underscore eso le permitirá transformar cadenas CamelCased en cadenas separadas por underscore. Entonces, podrías hacer esto:

FooBar.name.underscore.to_sym

Pero tendrá que instalar ActiveSupport solo para hacer eso, como dice ipsum.

Si no quiere instalar ActiveSupport solo para eso, puede aplicar el parche de mono underscore dentro String usted mismo (la función de subrayado se define en 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

119
2018-04-11 14:15



nombre del modelo en Rails 4 devuelve un ActiveModel::Name objeto que contiene muchos atributos más útiles "semánticos" tales como:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

Por lo tanto, debe usar uno de ellos si coinciden con el significado deseado, que probablemente sea el caso. Ventajas:

  • más fácil de entender tu código
  • su aplicación seguirá funcionando incluso en el caso (poco probable) de que Rails decida cambiar una convención de nomenclatura.

Por cierto, human tiene la ventaja de ser I18N consciente.


55
2017-09-03 09:09



primero: gem install activesupport

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

6
2018-04-11 14:09



Esto es para lo que fui:

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

2
2017-09-20 10:56