Come si converte il nome di una classe Ruby in un simbolo delimitato da trattini bassi?


95

Come posso trasformare a livello di codice un nome di classe,, FooBarin un simbolo :foo_bar,? ad esempio qualcosa di simile, ma che gestisce correttamente la custodia del cammello?

FooBar.to_s.downcase.to_sym

Risposte:


141

Rails viene fornito con un metodo chiamato underscoreche ti permetterà di trasformare stringhe CamelCased in stringhe underscore_separated. Quindi potresti essere in grado di farlo:

FooBar.name.underscore.to_sym

Ma dovrai installare ActiveSupport solo per farlo, come dice ipsum.

Se non si desidera installare ActiveSupport solo per questo, è possibile eseguire la patch di scimmia underscorein Stringse stessi (la funzione di sottolineatura è definita in 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
Grazie. Avevo paura che fosse un'estensione di Rails. :) Nessun problema, dato che in realtà sto usando Rails.
Josh Glover

2
Quindi avresti dovuto contrassegnare la tua domanda di conseguenza. Ecco, lascia che lo faccia per te ...
kikito

5
No, non ActiveRecord. ActiveSupport.
Rein Henrichs

Anzi, permettimi di cambiarlo
kikito

2
come fare il contrario?
user1406062

72

Rotaie 4 .model_name

In Rails 4, restituisce un ActiveModel::Nameoggetto che contiene molti attributi "semantici" più utili come:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

Quindi dovresti usarne uno se corrisponde al significato desiderato, il che è probabilmente il caso. Vantaggi:

  • più facile da capire il tuo codice
  • la tua app continuerà a funzionare anche nell'eventualità (improbabile) che Rails decida di modificare una convenzione di denominazione.

BTW, humanha il vantaggio di essere a conoscenza di I18N.


model_namefunziona anche per oggetti di esempio. Es: foo_bar.model_name. Se vuoi la lista completa scrivi foo_bar.model_name.inspectnella console rails o nel tuo debugger
ivanxuu

ed io cercavo l'opposto / indietro, classify, modelizeha non sembra funzionare.
Pysis

7

primo: gem install activesupport

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

Dovrebbe essere FooBar.to_s.underscore.to_sym, dal momento che sto cercando di convertire una classe (che è una costante) in un simbolo, che posso quindi fornire a Factory Girl . :)
Josh Glover

2

Ecco cosa ho scelto:

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 ha String#demodulizeche rimuoverà la parte prima ::.
amebe

@amoebe - grazie per le informazioni. Dipende da cosa stai lavorando: potresti non lavorare su un'app per rails (o anche su un'app Web).
Louis Sayers,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.