Use before_destroy on a model with paperclip

I have an application that I’m working on, this application has a demand that I will show the total files and the file total size inside a project. Here is my model:

Screen shot 2011-01-04 at 10.15.18 AM

Of course I have the option of using joins and so on and then calculating the file size, but because every project has many folders and every folder has many attachments this seems a bit off and not straight forward.

This is absolutely not the Rails way of doing things, so what I added a couple of fields inside the project model and here is what my model looked like after the change:

Screen shot 2011-01-04 at 10.18.59 AM

Now, I have straight forward fields inside my model, and the database work is very light, fast and straight forward. I added an observer for the attachment model, just to update the count and the total file size in the project model.

Here’s my observer’s code:

class AttachmentObserver < ActiveRecord::Observer
  observe :attachment

  def after_create(record)
    project = record.project
    if project
      project.increment!(:file_count, 1)
      project.increment!(:file_size, record.sketch_file_size) unless record.sketch_file_size.nil?
    end
    return true
  end

  def before_destroy(record)
    project = record.project
    if project
      project.decrement!(:file_count, 1)
      project.decrement!(:file_size, record.sketch_file_size) unless record.sketch_file_size.nil?
    end
    return true
  end
end

I added the observer to the application configuration.

Now, everything seemed to be working fine on create, when I deleted a model (deleted an attachment) I got a nil exception on the skecth_file_size property. The problem is that the paperclip plugin deleted the sketch file before my callback and so prevented me from using it.

This required a patch to the paperclip plugin.

Inside the paperclip plugin there’s a file called paperclip.rb Ffor me, it was line 242, I changed it from before_destroy to after_destory like so:

after_destroy :destroy_attached_files

Now, also in attachment.rb (also in paperclip plugin)

For me it was line 335:

unless instance.frozen?
  instance_write(:file_name, nil)
  instance_write(:content_type, nil)
  instance_write(:file_size, nil)
  instance_write(:updated_at, nil)
end

This worked like a charm and now my callback works, updating the model of the project as the files are adding and deleting, I don’t have to do complicated joins to get simple data.

Here’s how it looks in my application now:

Screen shot 2011-01-04 at 10.26.28 AM

This is the code I use to make it happen:

  <h2>
    <%= @project.name %>
  </h2><em><%= &quot;#{@project.file_count} files, #{number_to_human_size(@project.file_size)}"%></em>
<img src="http://feeds.feedburner.com/~r/KensoDev-en/~4/G_rk-SOF1Kk" height="1" width="1"/>
Thank you for your interest!

We will contact you as soon as possible.

Send us a message

Oops, something went wrong
Please try again or contact us by email at info@tikalk.com