Bagaimana cara saya secara terprogram mengubah nama kelas FooBar
,, menjadi simbol :foo_bar
,? Misalnya sesuatu seperti ini, tapi itu menangani kotak unta dengan benar?
FooBar.to_s.downcase.to_sym
Bagaimana cara saya secara terprogram mengubah nama kelas FooBar
,, menjadi simbol :foo_bar
,? Misalnya sesuatu seperti ini, tapi itu menangani kotak unta dengan benar?
FooBar.to_s.downcase.to_sym
Jawaban:
Rails dilengkapi dengan metode underscore
yang memungkinkan Anda untuk mengubah string CamelCased menjadi string underscore_separated. Jadi, Anda mungkin bisa melakukan ini:
FooBar.name.underscore.to_sym
Tetapi Anda harus menginstal ActiveSupport hanya untuk melakukan itu, seperti yang dikatakan ipsum.
Jika Anda tidak ingin menginstal ActiveSupport hanya untuk itu, Anda dapat melakukan monkey-patch underscore
ke String
diri Anda sendiri (fungsi garis bawah ditentukan di 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
Rel 4 .model_name
Di Rails 4, ia mengembalikan ActiveModel::Name
objek yang berisi lebih banyak atribut "semantik" yang berguna seperti:
FooBar.model_name.param_key
#=> "foo_bar"
FooBar.model_name.route_key
#=> "foo_bars"
FooBar.model_name.human
#=> "Foo bar"
Jadi Anda harus menggunakan salah satu dari mereka jika cocok dengan makna yang Anda inginkan, yang kemungkinan besar terjadi. Keuntungan:
BTW, human
memiliki keuntungan karena sadar I18N.
model_name
juga berfungsi untuk objek contoh. Ex: foo_bar.model_name
. Jika Anda ingin daftar lengkap tulis foo_bar.model_name.inspect
di konsol rel atau debugger Anda
classify
, modelize
tampaknya tidak bekerja.
pertama: gem instal aktif dukungan
require 'rubygems'
require 'active_support'
"FooBar".underscore.to_sym
FooBar.to_s.underscore.to_sym
, karena saya mencoba mengonversi kelas (yang merupakan konstanta) menjadi simbol, yang kemudian dapat saya berikan ke Factory Girl . :)
Inilah yang saya lakukan:
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
yang akan menghapus part sebelumnya ::
.