创建对象/哈希并将它们存储在数组中

时间:2014-07-20 12:13:44

标签: ruby-on-rails ruby ruby-on-rails-2

我正在尝试创建一个验证存储在我的数据库中的数据的函数。说我有一张桌子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

3 个答案:

答案 0 :(得分:2)

首先,MyHash不应该是骆驼案,但你可以做......

myhash = {}
Foo.each do |f|
    unless f.valid?
        myhash[f.id] = "blah blah blah"
    end
end

假设所有id都是唯一的,您只需要这个哈希值。这会将键值对设置为:idblah blah blah

答案 1 :(得分:2)

我相信您可以使用rejectmap编写上述内容:

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,它在任何时候都保证只包含有效元素。尝试将无效元素压入其中会引发错误,该错误可以被挽救并用于生成错误列表。