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


95

¿Cómo puedo convertir programáticamente el nombre de una clase FooBar, en un símbolo :foo_bar,? por ejemplo, algo como esto, pero que maneja correctamente el caso camel?

FooBar.to_s.downcase.to_sym

Respuestas:


141

Rails viene con un método llamado underscoreque le permitirá transformar cadenas CamelCased en cadenas undercore_separated. Entonces, es posible que pueda hacer esto:

FooBar.name.underscore.to_sym

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

Si no desea instalar ActiveSupport solo para eso, puede parchear underscoreen Stringusted 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

1
Gracias. Temía que esto fuera una extensión de Rails. :) No te preocupes, ya que en realidad estoy usando Rails.
Josh Glover

2
Entonces debería haber etiquetado su pregunta en consecuencia. Aquí, déjame hacerlo por ti ...
kikito

5
No, no ActiveRecord. ActiveSupport.
Rein Henrichs

De hecho, déjame cambiarlo
kikito

2
¿Cómo hacer lo contrario?
user1406062

72

Carriles 4 .model_name

En Rails 4, devuelve un ActiveModel::Nameobjeto que contiene muchos atributos más "semánticos" útiles 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 esos si coinciden con el significado deseado, que es probablemente 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, humantiene la ventaja de ser consciente de I18N.


model_nametambién funciona, por ejemplo, objetos. Ej foo_bar.model_name. : . Si desea la lista completa, escriba foo_bar.model_name.inspecten la consola de rieles o en su depurador
ivanxuu

y yo estaba buscando el frente / reverso, classify, modelizeno parece funcionar.
Pysis

7

primero: gema instalar activesupport

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

Debería serlo FooBar.to_s.underscore.to_sym, ya que estoy tratando de convertir una clase (que es una constante) en un símbolo, que luego puedo alimentar a Factory Girl . :)
Josh Glover

2

Esto es lo que busqué:

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 tiene String#demodulizeque eliminará la pieza anterior ::.
amebe

@amoebe - gracias por la información. Sin embargo, depende de en qué trabajes; es posible que no estés trabajando en una aplicación de rieles (o incluso en una aplicación web).
Louis Sayers
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.