如何将字符串转换为变量/字段?

时间:2013-06-05 07:45:34

标签: ruby-on-rails ruby

我是Ruby的新手,我想知道最好的做事方式是什么。

假设以下情形:

我有一个文本字段,用户可以在其中输入字符串。根据用户输入的内容(验证后),我想访问实例变量的不同字段。

示例:@zoo是一个实例变量。用户输入"monkey",我想访问@zoo.monkey。我怎么能在Ruby中做到这一点?

我想到的一个想法就是哈希:

zoo_hash = { "monkey" => @zoo.monkey, ... }

但我想知道是否有更好的方法来做到这一点?

谢谢!

4 个答案:

答案 0 :(得分:3)

在您的控制器中,您可以使用public_send(或甚至send)方法,如下所示:

def your_action
  @zoo.public_send(params[:your_field])
end

显然这是没有好,因为有人可以发布像delete_all之类的方法作为方法名称,因此您必须清理从表单中获得的值。举个简单的例子:

ALLOWED_METHODS = [:monkey, :tiger]

def your_action
  raise unless ALLOWED_METHODS.include?(params[:your_field])
  @zoo.public_send(params[:your_field])
end

答案 1 :(得分:3)

@zoo.attributes为您提供对象属性的哈希值。所以你可以像

那样访问它们
@zoo.attributes['monkey']

如果该属性不存在,这将给nil。调用不存在的方法将抛出NoMethodError

答案 2 :(得分:2)

有更好的方法可以做到这一点 - 你应该使用Object#send或(甚至更好,因为如果你尝试调用private或protected方法会引发错误)Object#public_send,就像这样:

message = 'monkey'
@zoo.public_send( message )

答案 3 :(得分:0)

您可以在班级中实施method_missing并让其查询@zoo以获取匹配方法。文档:http://ruby-doc.org/core-1.9.3/BasicObject.html#method-i-method_missing

require 'ostruct' # only necessary for my example

class ZooKeeper

  def initialize
    @zoo = OpenStruct.new(monkey: 'chimp')
  end

  def method_missing(method, *args)
    if @zoo.respond_to?(method)
      return @zoo.send(method)
    else
      super
    end
  end
end

keeper = ZooKeeper.new
keeper.monkey  #=> "chimp"
keeper.lion    #=> NoMethodError: undefined method `lion'