Topic: Looping arrays and adding based on array value

def total_disk_usage
    total_bytes = 0
    attachments.each { |a| total_bytes += a.size }
    Image.by_galleries(Gallery.by_page(pages)).each { |i| total_bytes += i.image_file_size }
    return total_bytes
end

any one got any ideas to make this cleaner?

p.s i'm not really getting the file size i'm just adding up the stored file size from the db.

Last edited by knodi (2008-12-31 20:47:40)

Better then best intranet/calendaring app Tofuapp.com

Re: Looping arrays and adding based on array value

Hi, my opinion is that calculations of this kind are always messy no matter how much icing you heap on top of it. I try to avoid them in web apps as much as possible.

If your user base is really small...maybe an internal office app, then I guess it's ok to do things this way. However, if you have thousands of users whom in turn have thousands of attachments and galleries, your application will suffer 'bottle-necking' when this action is called.

I would take a different approach here by adding a total_bytes column to your users(?) table. Then I would employ an after_create/before_destroy in your attachment model to update the total_bytes field. You could do the same with your gallery/page models(?). So now all you have to do is call @user.total_bytes and you get your value without having to rely on repetitive calculations.

On the other hand, if you need to perform an administrative action that gets the total disk usage for all your users, then you could use a calculation to figure it out. Hope this was somewhat helpful and check out my blog post for more on this type of thing.

http://www.webyfi.com/?p=91

Last edited by RailsRocks (2009-01-01 12:19:08)

http://www.webyfi.com
It's not the size of the app that matters, it's how you code it. ~ railsenvy

Re: Looping arrays and adding based on array value

Thx for the input. I"m hoping to get around 2k+ users to my site and fair mount of attachments/images so I'll just end up doing what you said do a create/destroy to keep track of total disk usage.

Thx again.

Better then best intranet/calendaring app Tofuapp.com

Re: Looping arrays and adding based on array value

As has already been said, keeping them updated in the db is the most efficient solution. But unless I'm missing something, if you just wanted to clean up your code (and make it more efficient) you could do something like:

    Attachment.sum('size') + Image.sum('image_file_size', { :some_conditions => :involving_pages })