views:

235

answers:

2

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
A: 

You would probably be better off using straight SQL for this if it's something that happens with any degree of frequency.

Azeem.Butt
+6  A: 

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 ]
)
vladr
Thanks, that really helped me a lot! I never thought about using joins before. :p
CalebHC