如何将Ruby类名称转换为下划线分隔的符号?


Answers:


141

Rails带有一种称为的方法,该方法underscore将允许您将CamelCased字符串转换为underscore_separated字符串。因此,您可以执行以下操作:

FooBar.name.underscore.to_sym

但是您必须安装ActiveSupport才能做到这一点,如ipsum所说。

如果你不想安装的ActiveSupport只是,你就可以猴子补丁underscoreString自己(下划线函数中定义的ActiveSupport ::变形器):

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

1
谢谢。我担心这是Rails扩展。:)不用担心,因为我实际上正在使用Rails。
乔什·格洛弗

2
然后,您应该相应地标记您的问题。在这里,让我为您做...
kikito 2011年

5
不,不是ActiveRecord。ActiveSupport。
Rein Henrichs

确实,让我更改一下
kikito 2011年

2
反向怎么办?
user1406062 2013年

72

滑轨4 .model_name

在Rails 4中,它返回一个ActiveModel::Name对象,其中包含许多有用的“语义”属性,例如:

FooBar.model_name.param_key
#=> "foo_bar"

FooBar.model_name.route_key
#=> "foo_bars"

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

因此,如果它们符合您的期望含义,则应使用其中一种,这很可能是这种情况。优点:

  • 更容易理解您的代码
  • 即使在Rails决定更改命名约定的(不太可能的)事件中,您的应用程序仍然可以运行。

顺便说一句,human具有I18N意识的优势。


model_name也适用于实例对象。例如:foo_bar.model_name。如果您想foo_bar.model_name.inspect在Rails控制台或调试器中写入完整列表
ivanxuu

我一直在寻找相反的/反向,classifymodelize似乎没有工作。
Pysis

7

第一:gem install activesupport

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

应该是FooBar.to_s.underscore.to_sym,因为我试图将一个类(一个常量)转换为一个符号,然后可以将其提供给Factory Girl。:)
Josh Glover

2

这是我追求的目标:

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

3
ActiveSupport具有String#demodulize将删除此部分的功能::
变形虫

@amoebe-感谢您提供信息。不过,这取决于您的工作-您可能不是在Rails应用程序(甚至是Web应用程序)上工作。
Louis Sayers
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.