Ruby常量查找

时间:2012-05-22 00:07:18

标签: ruby-on-rails ruby

这可能是一个简单的问题,但我试图从值中查找Ruby中的常量名称。例如:

class Xyz < ActiveRecord::Base
  ACTIVE    = 1
  PENDING   = 2
  CANCELED  = 3
  SENT      = 4
  SUSPENDED = 5
end

我的数据库中的状态为1。我想基于此检索ACTIVE,以便我可以在视图中显示它。

这样做的好方法是什么?

5 个答案:

答案 0 :(得分:7)

class Module
  def constant_by_value( val )
    constants.find{ |name| const_get(name)==val }
  end
end

class Xyz
  ACTIVE    = 1
  PENDING   = 2
  CANCELED  = 3
  SENT      = 4
  SUSPENDED = 5
end

p Xyz.constant_by_value(4)
#=> :SENT

但是,我不会这样做:使用程序化名称作为视图的值似乎是个坏主意。您可能会遇到想要更改显示名称的情况(可能“暂停”应显示为“暂停”),然后您必须重构代码。

我使用模型中的常量在视图或控制器中放置了一个映射:

status_name = {
  Xyz::ACTIVE    => "Active",
  Xyz::PENDING   => "Pending", 
  Xyz::CANCELED  => "Canceled", 
  Xyz::SENT      => "Away!", 
  Xyz::Suspended => "On Hold"
}
@status = status_name[@xyz.status_id]

答案 1 :(得分:5)

我会把它放到一个常数数组中。

class xzy < ActiveRecord::Base
  STATUSES = %w{ACTIVE PENDING CANCELLED SENT SUSPENDED}

  def get_status
    STATUSES[self.status-1]
  end

  def get_status_id(name)
    STATUSES.index(name) + 1
  end
end

#get_status中的减1和#get_status_id中的+ 1适用于零索引数组。我添加了第二种方法,因为我不时发现自己需要这种方法。

答案 2 :(得分:3)

如果你的常量并不总是从小整数中抽出,你也可以尝试:

class Xyz < ActiveRecord::Base
  class << self
    def int_to_status(x)
      constants.find{ |c| const_get(c) == x }
    end
  end
end

答案 3 :(得分:2)

class Xyz < ActiveRecord::Base

  STATUSES = { 
    1 => ACTIVE,
    2 => PENDING,
    3 => CANCELED,
    4 => SENT,
    5 => SUSPENDED
  }

  def status_name
    STATUSES[ status ]   
  end

  def status_by_name( name )
    STATUSES.key( name ) 
  end

end

答案 4 :(得分:0)

扩展@Phrogz我认为这也是一个选择:

module Xyz
  ACTIVE    = 1
  PENDING   = 2
  CANCELED  = 3
  SENT      = 4
  SUSPENDED = 5      

  def self.constant_by_value( val )
    constants.find{ |name| const_get(name)==val }
  end
end

Xyz.constant_by_value(2)
#=> :PENDING

我之所以提到这一点,是因为有时我会发现将常量与特定类完全隔离起来很方便。