I'm using Paperclip gem in my new project for storing images. There's also simple custom Paperclip processor I wrote to crop images according to crop parameters, stored in my model's virtual attributes.
So client transfers form with model's actual db fields and crop_x, crop_y, crop_w, crop_h attributes, controller creates new instance based on "params" --- that's going well -- I checked it, but then some weird things are taking place.
here's my model:
class Jewel < ActiveRecord::Base
has_many :line_items
belongs_to :material
******* some code *********
before_save :debugmeBS
validates :category_id, :presence => true
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
attr_accessible :name, :category_id, :price, :crop_x, :crop_y,
:crop_w, :crop_h, :image
after_update :reprocess_image, :if => :need_to_crop?
has_attached_file :image, :styles => { :full => "900x", :smallthumb => "80x80>" },
:processors => [:cropper, :thumbnail]
before_post_process :debugmePP
def need_to_crop?
# debugger
!crop_x.blank? && !crop_y.blank? &&!crop_w.blank? &&!crop_h.blank?
end
private
def debugmeBS
debugger
x=2
end
def debugmePP
debugger
x=3
end
end
Debugger placed in my custom processor shows that crop_x, crop_y and others virtual attributes are blank (by invoking "need_to_crop?" method) meanwhile other not-virtual ones are set properly. To track-down error I placed two "before_"-events: before_save and Paperclip's before_post_process. Turns out that before_post_process is invoked before before_save and on the moment all my "crop_" attributes are nil, but on the moment of before_save fire, those are properly set up.
so the question is why? and how to set my virtual attributes to be accessed by Paperclip processor? Thank you
I hit the same thing as well. Looking at the code for Paperclip (see callbacks.rb, attachment.rb, and paperclip.rb under lib/paperclip/), it seems the before_post_process and before__post_process callbacks are invoked when the file is assigned to the attribute. My guess is that this is happening before the other attributes on the model are set.
UPDATE: I asked on the GitHub Issues for the Paperclip project, and what I wrote above was confirmed. The timing of the processing does depend on when the attribute is assigned. Since attributes are assigned alphabetically, depending on the name of the , it can be assigned before any of the other attributes.
For a workaround, you can do:
def create
avatar = params[:resource].delete(:avatar)
resource = Resource.new(params[:resource]
resource.avatar = avatar
resource save
end