我正在尝试创建一个验证存储在我的数据库中的数据的函数。说我有一张桌子Foo。对于Foo中的每个项目,我调用一个函数,即使用一组检查验证它的Bar。如果数据不正确,我将项目ID与散列中失败原因的描述一起存储。哈希被推送到一个数组。
ErrorList = []
MyHash = Hash.new {|h,k| h[k]=[]}
Foo.each do |f|
unless f.valid?
MyHash["foo_id"] = f.id
MyHash["description"] = "blah blah blah"
ErrorList.push MyHash
end
end
在执行结束时,由于哈希条目被覆盖,因此数组中的所有条目都是相同的。有没有办法可以使用这个哈希在我的数组中存储不同的id和描述。否则,是否有办法使用对象来克服这个问题?
我正在使用rails版本2.3.5
答案 0 :(得分:2)
首先,MyHash不应该是骆驼案,但你可以做......
myhash = {}
Foo.each do |f|
unless f.valid?
myhash[f.id] = "blah blah blah"
end
end
假设所有id都是唯一的,您只需要这个哈希值。这会将键值对设置为:id
:blah blah blah
答案 1 :(得分:2)
error_list = foos.reject(&:valid?).map do |f|
{ "foo_id" => f.id, "description" => "blah blah blah" }
end
这将创建一个哈希列表,每个哈希都包含所有无效"foo_id"
的{{1}}和"description"
。
要使 代码正常工作,您需要确保为列表中的每个元素创建新哈希,而不是重新使用已创建的哈希:
foos
答案 2 :(得分:1)
Matz本人指出,随着时间的推移,“面向对象”变得如此普遍,以至于我们倾向于低估其力量。不过听起来很老套,Ruby是一种OO语言,你应该用它编写OO程序。有许多可能的方法。一个可能的例子是
class ValidatedTable < Array
def self.new array=[]
array.each_with_object new do |e, o| o << e end unless array.empty?
super
end
def << element
fail TypeError, "blah blah blah" unless element.valid?
super
end
end
现在,有ValidatedTable
#<<
方法抱怨无效输入,我们很容易实现您的目标:
validated_table, error_list = Foo.each_with_object [ ValidatedTable.new, [] ] do |e, o|
begin
o[0] << e
rescue TypeError => msg
e[1] << { id: e.id, description: msg.to_s }
end
end
此解决方案的独特之处在于它创建了一个特殊的数组子类ValidatedTable
,它在任何时候都保证只包含有效元素。尝试将无效元素压入其中会引发错误,该错误可以被挽救并用于生成错误列表。