Jak programowo zmienić nazwę klasy FooBar
na symbol :foo_bar
? np. coś w tym rodzaju, ale czy to dobrze radzi sobie z wielbłądem?
FooBar.to_s.downcase.to_sym
Jak programowo zmienić nazwę klasy FooBar
na symbol :foo_bar
? np. coś w tym rodzaju, ale czy to dobrze radzi sobie z wielbłądem?
FooBar.to_s.downcase.to_sym
Odpowiedzi:
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 underscore
do String
siebie (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
Szyny 4 .model_name
W Railsach 4 zwraca ActiveModel::Name
obiekt, 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:
BTW, human
ma tę zaletę, że jest świadomy I18N.
model_name
działa również na przykład obiekty. Np foo_bar.model_name
. : . Jeśli chcesz mieć pełną listę napisz foo_bar.model_name.inspect
w konsoli
classify
, modelize
że nie działa.
po pierwsze: gem install activesupport
require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym
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 . :)
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
String#demodulize
który usunie część wcześniej ::
.