Nasty deep nested loop in Rails
-
25-09-2019 - |
Question
I have this nested loop that goes 4 levels deep to find all the image widgets and calculate their sizes. This seems really inefficient and nasty! I have thought of putting the organization_id in the widget model so I could just call something like organization.widgets.(named_scope), but I feel like that's a bad short cut. Is there a better way? Thanks
class Organization < ActiveRecord::Base
...
def get_image_widget_total
total_size = 0
self.trips.each do |t|
t.phases.each do |phase|
phase.pages.each do |page|
page.widgets.each do |widget|
if widget.widget_type == Widget::IMAGE
total_size += widget.image_file_size
end
end
end
end
end
return total_size
end
...
end
Solution
For performance and memory considerations you should consider issuing a single SELECT SUM(total_size)
statement, e.g.
Widget.sum(
:total_size,
:conditions => [ 'widget_type = ? AND organization_id = ?',
Widget::IMAGE', self.id ],
:joins => [ :pages, :phases, :trips ]
)
OTHER TIPS
You would probably be better off using straight SQL for this if it's something that happens with any degree of frequency.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow