2011-10-19 4 views
1

J'utilise un trombone pour joindre des fichiers à un de mes modèles. Ce que je voudrais faire est, après que le modèle ait été sauvé et le dossier écrit sur le disque, je dois alors mettre à jour un autre attribut dans mon modèle au sujet du dossier (un CRC). Comme paperclip n'écrit pas le fichier sur le disque tant que le .save n'a pas été appelé, mon premier réflexe était d'utiliser le callback after_save. Lorsque je fais cela, j'obtiens une erreur "SystemStackError (stack level too deep):". Puis j'ai essayé de faire un callback after_commit qui semble fonctionner un peu mieux. Par exemple, si j'affecte simplement mon crc avec:quand mettre à jour l'enregistrement après l'enregistrement?

self.crc = "TEST" 
self.save 

Cela fonctionne. Toutefois, si je tente de faire ma vraie mission, avec ceci:

self.crc = "0x" + IO.read(self.patchfile.path, 4, 0x20).unpack("H8").join 
self.save 

WEBrick avorte avec:

/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 

Je pense que je fais ce mal ...

+0

Je dois mentionner que pendant qu'il tue WEBrick, il ne fonctionne réellement. Lorsque je le redémarre, l'attribut CRC est correctement défini. En outre, dans les erreurs énumérées ci-dessus, il y en a beaucoup plus, je viens de poster la queue. –

Répondre

5

Vous » re à l'intérieur d'un rappel after_save, et vous appelez save. Cela va déclencher à nouveau votre callback, d'où vient votre erreur de boucle infinie "stack level too deep". Envisagez d'utiliser un DelayedJob que vous mettez en file d'attente à partir de votre rappel. Laissez une tâche d'arrière-plan gérer le travail d'attribution de votre CRC. Cependant, vous aurez toujours une boucle infinie, mais cette fois une boucle infinie de tâches en file d'attente.

Jetez un coup d'oeil à: How can I avoid running ActiveRecord callbacks? pour obtenir des conseils sur l'annulation de vos rappels dans certaines conditions.

Edit:

Vous pouvez également écrire votre propre post-processeur de Paperclip. Jetez un coup d'œil aux sections «Post-traitement» et «Processeurs de pièces jointes personnalisées» dans le fichier readme, et parcourez le code pour voir comment fonctionnent les processeurs existants.

https://github.com/thoughtbot/paperclip

+0

D'accord, je vais jeter un coup d'oeil. Une autre question serait, est-il un moyen d'accéder au contenu du fichier avant qu'il ne soit enregistré sur le disque? Dans ce cas, je n'aurais pas besoin de faire ça. –

+0

Très bien, je l'ai obtenu avec un callback conditionnel, en utilisant le ': if =>: skip_callback' et ensuite avoir une méthode skip_callback qui vérifie si crc est nul. –

Questions connexes