2010-04-24 2 views
0

У меня есть массив объектов ActiveRecord, каждый из которых имеет свой собственный соответствующий массив ошибок. Я хочу сгладить все и получить только уникальные значения в один массив. Таким образом, массив верхнего уровня может выглядеть следующим образом:Ruby эффективный способ построения массива из массива массивов

foo0 = Foo.new 
foo1 = Foo.new 
foo2 = Foo.new 
foo3 = Foo.new 

arr = [foo0, foo1, foo2, foo3] 

Каждый из этих объектов может потенциально иметь множество ошибок, и я хотел бы получить только уникальное сообщение из них и поместить их в другой массив, например, error_arr. Как бы вы сделали это «Ruby»?

ответ

4

Код:

arr = [foo0, foo1, foo2, foo3] 
arr.map{|record| record.errors.full_messages }.flatten.uniq 

Я надеюсь, что это то, что вы хотите. Метод очень точно соответствует вашему описанию («flatten», «uniq»).

1
require 'set' 
error_arr = [foo0, foo1, foo2, foo3].reduce(Set.new) do |set, arr| 
    set.merge(arr.errors) 
end.to_a 

EDIT: Этот ответ работает, если каждый foo имеет массив ошибок, что, по-видимому, не так. Я оставлю ответ, если у кого-то есть аналогичная проблема с реальными массивами.

+0

ActiveRecord.errors не является истинным массивом. Функция Merge генерирует исключение, если оно сливается с набором. –

0

Попробуйте это:

Если вы хотите получать сообщения об ошибках просто в массиве, то сделайте следующее:

def merge_errors(arr) 
    [].tap do |errors| 
    arr.each{|m| errors += m.errors.full_messages} 
    end 
end 

Если вы хотите получать сообщения об ошибках в ActiveRecord :: класс Ошибки, затем выполните следующие действия:

def merge_errors(arr) 
    ActiveRecord::Errors.new({}).tap do |all_error| 
    arr.each{|model| model.errors.each_full{|m| all_error.add_to_base(m)} 
    end 
end 

Теперь вы можете использовать функцию следующим образом:

arr = [foo0, foo1, foo2, foo3] 
errors = merge_errors(arr) 
unless errors.empty? 
    # handle error 
end 
Смежные вопросы