问题
I am using paperclip to attach files to a Model of mine. What I would like to do is, after the model has been saved and the file written to disk, I need to then update another attribute in my model about the file (a CRC). Since paperclip does not write the file to disk until after the .save has been called, my first thought was to use the after_save callback. When I do this, I get a "SystemStackError (stack level too deep):" error. Then I tried to do a after_commit callback which seems to be working a little better. For example, if I simply assign my crc with:
self.crc = "TEST"
self.save
This works. However, If I try to do my real assignment, with this:
self.crc = "0x" + IO.read(self.patchfile.path, 4, 0x20).unpack("H8").join
self.save
WEBrick aborts with:
/usr/local/rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x180048) [0x290048]
/usr/local/rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(rb_yield+0x56) [0x294c46]
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Aborted
So I am thinking I am doing this wrong...
回答1:
You're inside of an after_save
callback, and you're calling save
. That's going to trigger your callback again, which is where your infinite loop "stack level too deep" error is coming from.
Consider using a DelayedJob
which you queue from your callback. Let a background task handle the work of assigning your CRC. However, you'll still have an infinite loop happening, but this time an infinite loop of queued jobs.
Take a look at: How can I avoid running ActiveRecord callbacks? for tips on skipping your callbacks under certain conditions.
Edit:
You might also want to write your own Paperclip post processor. Take a look at the sections on "Post Processing" and "Custom Attachment Processors" in the readme, and dig through the code to see how the existing processors operate.
https://github.com/thoughtbot/paperclip
来源:https://stackoverflow.com/questions/7824606/when-to-update-record-after-save