Amazon S3にjquery_file_uploadでファイルをアップしたら動かなくなったよ

jQuery_file_uploadを利用して画像ファイルをS3にアップする仕組みを作ってみました。

一旦アプリケーション配下にアップロードする方式で実装。一通り要件通り動作することを確認。
Herokuを使って動かす想定。Herokuはアプリ内のpublicとかにファイルを保存できないことから、S3を利用するように書き換えを開始・・・。
このあたりの設定とかは色々なサイトで説明が書かれていますね。ここのサイトを参考にさせてもらいました。アップロードと、uploadTemplateでのサムネイル表示あたりまでは順調に書き換えできました。


downloadTemplateが全然うごかない・・・

Amazon S3にpaperclipでファイルをアップロードしたあとの戻りの値がローカルに保存した場合とは異なっているようです。また、サーバからjsonで返してくるレスポンスもとれていないようでした。


done:を自分で作成することにします。
※最終的なdoneのコードは記事の末尾にのせてます。

こんな感じにして、jqXHRからレスポンスをTextで取得。
JSON形式に変換して、renderTemplateしてあげる。

var res = data.jqXHR.responseText;
var jsonData = $.parseJSON(res);

template = fu._renderDownload(jsonData)
                     .appendTo($('#fileupload .files'));

これでdownloadTemplate問題が解決しました。

続いて、アップロードが終わったあとにuploadTemplateが消えない問題が発生。
どうも、レスポンスのdata.contextに、uploadTemplateが格納されているようです。
なので、こんな感じにしてみました。

$(data.context).remove();

jquery_file_uploadのソースの中にはこんな記述は無いため、もっと良い書き方がありそうですが・・・
$.Deferred()を利用して制御しているように見えましたが、うまく再利用できませんでした。


ということで、最終的にはこうなりました。(他の部分は割愛)

<script type="text/javascript" charset="utf-8">
    $(function () {
        // Initialize the jQuery File Upload widget:
        $('#fileupload').fileupload({
            done: function(e, data) {
                // Load existing files:
                var fu = $(this).data('blueimp-fileupload') ||
                                $(this).data('fileupload'),
                        template;
                var res = data.jqXHR.responseText;
                var jsonData = $.parseJSON(res);

                // Render DownloadTemplate
                template = fu._renderDownload(jsonData)
                        .appendTo($('#fileupload .files'));
                // Force reflow:
                fu._forceReflow(template);
                // downloadTemplate Fade-in
                template.addClass('in');

                // remove upload
                $(data.context).remove();
                // remove loading
                $('#loading').remove();
            }
        });
    });
</script>

解決するのに5時間くらいかかった・・・