What I needed was the pipe operator! It was of course just doing what I was telling it to - pushing the results of itself onto the current element in the array. Only when the rootsections loop completes does it start a new array element.
The 'pipe' (|
) is a different array merge operator which appends what's to the right of it onto the end of the array on the left.
all_sections | fetch_all_sections(standard, section, depth)
The pipe operator changed how depth worked so instead I just counted the number of "." in sortlabel:
depth = section.sortlabel.split('.').length -1
The full method:
# Calls itself for each section recursively to fetch all possible children
def fetch_all_sections(standard, section = nil, depth = 0)
all_sections = []
if section.nil?
rootsections = standard.sections.sorted
if ! rootsections.nil?
rootsections.each_with_index do |section, i|
depth = section.sortlabel.split('.').length - 1
all_sections << fetch_all_sections(standard, section, depth).first
end
end
else
all_sections << {:id => section.id, :sortlabel => section.sortlabel, :title => section.title, :depth => depth}
section.children.sorted.each do |section|
all_sections | fetch_all_sections(standard, section)
end
end
return all_sections
end
If someone seeing this is considering something similar but starting from scratch, consider an Active Record Nesting gem: https://www.ruby-toolbox.com/categories/Active_Record_Nesting
UPDATE: I added .first within the rootsections loop. This is because I inadvertently built an array orof arrays, each containing 1 hash. What I wanted was an array of hashes. Much easier retrieval now!