callback issue with carrierwave and mongoid
I am using carrierwave and mongoid on a rails 3 application and am having an issue with an after_save callback. Consider the following
class Video
include Mongoid::Document
field :name
mount_uploader :file, VideoUploader
after_create :enqueue_for_encoding
protected
def enqueue_for_encoding
// point your encoding service to where it expects the permanent file to reside
// in my case on s3
end
end
My issue is that in my enqueue_for_encoding
method, file.url points to the local tmp directory not the s3 directory.
How do I get my enqueue_for_encoding
method to be calle开发者_Go百科d when file.url points to s3?
Thanks!
Jonathan
Check out carrierwave's howto page on Callbacks
https://github.com/jnicklas/carrierwave/wiki/How-to%3A-use-callbacks
It worked for me
Okay, I figured it out. To took a bit of hacking. So currently carrierwave does not expose an after_create hook, all of it persisting and processing happens in the after_save callback. Here is the code I used to work around it:
# Video.rb
mount_uploader :file, VideoUploader
# overwrite the file setting to flag the model that we are creating rather than saving
def file=(obj)
@new_file = true
super(obj)
end
# chain the store_file! method to enqueue_for_encoding after storing the file AND
# if the file is new
alias_method :orig_store_file!, :store_file!
def store_file!
orig_store_file!
if @new_file #means dirty
@new_file = false
enqueue_for_encoding
end
true
end
UPDATE
Woops -- that didn't work. It almost did -- the url is correct, but it is being fired permanently. Meaning the file is still in process of being loaded, and is not fully stored when enqueue_for_encoding is called
It is possible to set your enqueue_for_encoding
callback on the uploader itself. But I prefer to do it this way:
class Video
# mount the uploader first:
mount_uploader :file, VideoUploader
# then add the callback:
after_save :enqueue_for_encoding, on: :create
end
You could try removing your after_create
callback in the model and add the following to your uploader:
# video_uploader.rb
process :encode
def encode
model.enqueue_for_encoding
end
The process
callbacks are called after the file is saved (I think) which should allow you to hook in once your file is up on S3.
精彩评论