2013-12-20 3 views
0

Я хотел, чтобы преобразовать вложенный массив из ActiveRecord::Relation объектов, как это:Сведение массив ActiveRecord :: Relation экземпляров

# Event is a ActiveRecord::Base derived class 
r1 = [ [ Event.where(id: 1) ], Event.where(id: 1)] 
# => [ [ #<ActiveRecord::Relation []> ], #<ActiveRecord::Relation[]> ] 

в:

[#<ActiveRecord::Relation []>, #<ActiveRecord::Relation []> ] 

Array#flatten разработан, чтобы сделать это идеально. К сожалению, он не возвращает ожидаемый результат:

r1.flatten # => [] 

Enumrable#map не работает либо:

r1.map{|m| m.limit(10) } # => [] 

Enumerable#flat_map возвращает немного другой результат:

r1.flat_map{|m| m.limit(10) } # => [ #<ActiveRecord::Relation []> ] 

Наконец, цикл по массиву и нажатие в другой пустой массив возвращает ожидаемый результат:

z = [] 
r1.each {|e| if e.is_a?(Array) then e.each{|x| z << x} else z << e end} 
# => [#<ActiveRecord::Relation []>, #<ActiveRecord::Relation []> ] 

В чем причина этих различий?

Я использую

  • рубин 2.0.0p353 (2013-11-22 ревизия 43784) [x86_64-darwin13.0.0]
  • (построен с помощью GCC РВМ + Homebrew)
  • Rails 4.0.2
  • MacOS X Mavericks

ответ

2

Когда вы выполните .flatten, метод вызовет SQL-запрос, завернутый связанными отношениями. Результат запросов будет сглажен.

В вашем случае, похоже, оба запроса возвращается пустой набор записей, вызывая

r1 = [ [ Event.where(id: 1) ], Event.where(id: 1)] 

быть оценены как

r1 = [ [[]] , []] 

что indeeds сглаживается в

[] 

Если вы пытаетесь код с областью действия, которая дает результат, то вы увидите, что сглаживание вернет массив записей.

Для того, чтобы сгладить области, вам нужен индивидуальный метод, как и вы. Вот расширенная версия, которая работает с уровнями illimitate.

def flatten_scopes(scopes) 
    scopes.inject([]) { |a,r| r.is_a?(Array) ? a += flatten_scopes(r) : a.push(r) } 
end 

flatten_scopes(r1) 
+0

Спасибо. Правильно. Введут подобные методы в подходящее место. – shigeya

2

вы получаете результат, который вы видите, потому что, когда вы перечислить соотношение (или преобразовать его в массив), он не содержит любые элементы.

Вы можете видеть это в распечатке отношения, которое имеет [] непосредственно перед >. Если в нем что-то есть, вы увидите элементы в скобках.

+0

Благодарим за комментарий. – shigeya

Смежные вопросы