2014-10-07 47 views
0

我正在寻找一种方法来从字符串中分配模型属性。这是在具有不同属性的多个模型共享的关注之内,所以我不能仅仅强制给属性名称编码。从字符串中分配模型属性的替代方法

我在使用一个字符串没有问题检索属性“发送”:

self.send("#{attribute_name}") 

,但我有难度指定字符串中的属性。 E.g

self."attribute_name" = "<user input>" 

可怕的eval函数做什么,我需要的,但它显然是可怕的不安全:

eval("self.#{attribute_name} = '<user input>'") 

有我缺少的是可以实现这个没有的eval函数?或者我的方法都是错误的,我应该回到制图板?谢谢。

回答

1

鉴于该属性具有公共setter方法,这个工程:

class X 
    attr_accessor :foo 

    def dynamic_set(attr_name, value) 
    public_send("#{attr_name}=", value) 
    end 
end 

x = X.new 
x.dynamic_set("foo", "bar") 
p x.foo 
# => "bar" 
+0

真棒正是我需要的 - 太感谢你了! – RichardAE 2014-10-07 12:42:49

+1

请注意,如果方法不存在或不公开,public_send会引发异常。 – Jesper 2014-10-07 12:44:48

+1

刚刚看到您的编辑 - 这看起来像一个伟大的实施,再次感谢!当它让我(显然是7分钟)时,我将它标记为答案。 – RichardAE 2014-10-07 12:45:53

1

你应该把它们保存为实例变量。

要获取:

instance_variable_get("@#{attribute_name}") 

设置:

instance_variable_set("@#{attribute_name}", user_input) 
+0

这不是不明智的,因为用户可以用这种方式设置一个任意的实例变量吗?所以你可以通过将大量的实例变量设置为非常大的字符串值来攻击系统? – Jesper 2014-10-07 13:16:57

+0

@Jesper OP写道:“我不能硬编码属性名称。”如何在不违反此要求的情况下做到这一点? – sawa 2014-10-07 13:18:56

+0

是的,我错过了。但是,从我的回答被接受以来,OP似乎并不完全是指他或她写了什么。 – Jesper 2014-10-07 13:39:32

相关问题