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


Wie kann ich einen Klassennamen programmgesteuert umwandeln, FooBarin ein Symbol, :foo_bar? z.B. etwas wie das, aber das behandelt Kamelfall richtig?

FooBar.to_s.downcase.to_sym

75
2018-04-11 14:03


Ursprung


Antworten:


Rails kommt mit einer Methode namens underscore Dadurch können Sie CamelCased-Zeichenfolgen in string_separated-Zeichenfolgen umwandeln. So können Sie dies möglicherweise tun:

FooBar.name.underscore.to_sym

Aber Sie müssen ActiveSupport installieren, nur um das zu tun, wie Ipsum sagt.

Wenn Sie ActiveSupport nicht nur für diesen Zweck installieren möchten, können Sie einen Patch erstellen underscore in String selbst (die Unterstrichfunktion ist in definiert ActiveSupport :: Beugung):

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



Modellname in Rails 4 gibt ein zurück ActiveModel::Name Objekt, das viele nützliche "semantische" Attribute enthält, wie:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

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

  • einfacher, deinen Code zu verstehen
  • Ihre App funktioniert auch in dem (unwahrscheinlichen) Ereignis, dass Rails eine Namenskonvention ändert.

BTW, human hat den Vorteil, I18N bewusst zu sein.


55
2017-09-03 09:09



Erstens: Gem install activesupport

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

6
2018-04-11 14:09



Hier ist, was ich wollte:

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