Wie konvertiere ich einen Ruby-Klassennamen in ein durch einen Unterstrich getrenntes Symbol?

95

Wie kann ich einen Klassennamen programmgesteuert FooBarin ein Symbol verwandeln :foo_bar? zB so etwas, aber das behandelt Kamelkoffer richtig?

FooBar.to_s.downcase.to_sym
Josh Glover
quelle

Antworten:

141

Rails wird mit einer Methode namens underscoregeliefert, mit der Sie CamelCased-Strings in underscore_separated-Strings umwandeln können. Möglicherweise können Sie Folgendes tun:

FooBar.name.underscore.to_sym

Sie müssen jedoch ActiveSupport installieren, um dies zu tun, wie ipsum sagt.

Wenn Sie ActiveSupport nicht nur dafür installieren möchten, können Sie Affen-Patches underscorein sich Stringselbst erstellen (die Unterstrichfunktion ist in ActiveSupport :: Inflector definiert ):

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
Kikito
quelle
1
Vielen Dank. Ich hatte Angst, dass dies eine Rails-Erweiterung war. :) Keine Sorge, ich benutze tatsächlich Rails.
Josh Glover
2
Dann hätten Sie Ihre Frage entsprechend markieren sollen. Hier, lass es mich für dich tun ...
Kikito
5
Nein, nicht ActiveRecord. ActiveSupport.
Rein Henrichs
Lassen Sie es mich in der Tat ändern
Kikito
2
Wie mache ich das Gegenteil?
user1406062
72

Schienen 4 .model_name

In Rails 4 wird ein ActiveModel::NameObjekt zurückgegeben, das viele nützliche "semantischere" Attribute enthält, wie z.

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

Sie sollten also eine davon verwenden, wenn sie Ihrer gewünschten Bedeutung entspricht, was wahrscheinlich der Fall ist. Vorteile:

  • einfacher, Ihren Code zu verstehen
  • Ihre App funktioniert auch dann noch, wenn Rails (unwahrscheinlich) beschließt, eine Namenskonvention zu ändern.

Übrigens, humanhat den Vorteil, I18N-fähig zu sein.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
model_namefunktioniert auch zum Beispiel Objekte. Bsp. : foo_bar.model_name. Wenn Sie die vollständige Liste möchten, schreiben Sie foo_bar.model_name.inspectin die Rails-Konsole oder in Ihren Debugger
ivanxuu
und ich suchte das Gegenteil / Gegenteil classify, modelizeschien nicht zu funktionieren.
Pysis
7

Erstens: gem install activesupport

require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym
ipsum
quelle
Sollte sein FooBar.to_s.underscore.to_sym, da ich versuche, eine Klasse (die eine Konstante ist) in ein Symbol umzuwandeln, das ich dann an Factory Girl weitergeben kann . :)
Josh Glover
2

Folgendes habe ich gewählt:

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
Louis Sayers
quelle
3
ActiveSupport hat String#demodulizedas Teil vorher zu entfernen ::.
Amöbe
@amoebe - danke für die Info. Hängt jedoch davon ab, woran Sie arbeiten - möglicherweise arbeiten Sie nicht an einer Rails-App (oder sogar einer Web-App).
Louis Sayers