Jak przekonwertować nazwę klasy Ruby na symbol rozdzielany podkreśleniem?

98

Jak programowo zmienić nazwę klasy FooBarna symbol :foo_bar? np. coś w tym rodzaju, ale czy to dobrze radzi sobie z wielbłądem?

FooBar.to_s.downcase.to_sym
Josh Glover
źródło

Odpowiedzi:

145

Railsy są wyposażone w metodę o nazwie underscore, która pozwoli ci przekształcić ciągi CamelCased w ciągi podkreślone_separated. Więc możesz to zrobić:

FooBar.name.underscore.to_sym

Ale będziesz musiał zainstalować ActiveSupport, aby to zrobić, jak mówi ipsum.

Jeśli nie chcesz instalować ActiveSupport tylko po to, możesz małpa-patch underscoredo Stringsiebie (funkcja podkreślenia jest zdefiniowana w 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
kikito
źródło
1
Dzięki. Bałem się, że to rozszerzenie Railsów. :) Nie martw się, tak naprawdę używam Railsów.
Josh Glover,
2
W takim razie powinieneś był odpowiednio oznaczyć swoje pytanie. Pozwól, że zrobię to za Ciebie ...
kikito
5
Nie, nie ActiveRecord. ActiveSupport.
Rein Henrichs
Rzeczywiście, pozwólcie, że to
zmienię
2
jak zrobić odwrotnie?
user1406062
73

Szyny 4 .model_name

W Railsach 4 zwraca ActiveModel::Nameobiekt, który zawiera wiele przydatnych, bardziej „semantycznych” atrybutów, takich jak:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

Powinieneś więc użyć jednego z nich, jeśli pasują do twojego pożądanego znaczenia, co prawdopodobnie ma miejsce. Zalety:

  • łatwiejsze do zrozumienia kodu
  • Twoja aplikacja będzie nadal działać nawet w (mało prawdopodobnym) przypadku, gdy Railsy zdecydują się zmienić konwencję nazewnictwa.

BTW, humanma tę zaletę, że jest świadomy I18N.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
źródło
model_namedziała również na przykład obiekty. Np foo_bar.model_name. : . Jeśli chcesz mieć pełną listę napisz foo_bar.model_name.inspectw konsoli
railsów
i szukałem przeciwieństwa / odwrotności, wydawało się classify, modelizeże nie działa.
Pysis
7

po pierwsze: gem install activesupport

require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym
ipsum
źródło
Powinno być FooBar.to_s.underscore.to_sym, ponieważ próbuję przekształcić klasę (która jest stałą) w symbol, który mogę następnie przekazać Factory Girl . :)
Josh Glover
2

Oto, do czego poszedłem:

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
źródło
3
ActiveSupport ma, String#demodulizektóry usunie część wcześniej ::.
ameba
@amoebe - dzięki za informację. Zależy to jednak od tego, nad czym pracujesz - możesz nie pracować z aplikacją railsową (lub nawet aplikacją internetową).
Louis Sayers,