4

Heroku に Carrierwave を使用したアプリがあります。ページには、2 つのフォームがあります。画像をアップロードするための 1 つの ajax フォームと、オブジェクトの作成に必要な追加情報のための 1 つの通常のフォームです。私の Carrierwave マウントが:pictureであると仮定すると、ajax フォームが送信されるたびに、画像がパブリック フォルダーに一時的に保存され、そのパスが として返され:picture_cacheます。次に、2 番目のフォームはそれを使用して、2 番目の要求で新しいオブジェクトを使用してどの画像を作成するかを認識します。これは、単一の dyno では問題なく機能します。

異なる dyno は、互いのファイルシステムを認識していません。したがって、2 番目のフォームを送信するリクエストが最初のフォームのリクエストと同じ dyno にヒットしない場合、画像を見つけることができません。

誰かがこの問題に取り組みましたか?

4

1 に答える 1

2

カスタム モデルを使用し、tmp ファイルを含むすべてのファイルを mongodb に保存します。アップロードは tmp としてマークされます。モデルが「保存」されているものは、「tmp」フラグを削除するだけです。このようにして、すべてのノードが常にすべてのイメージを認識します。多くのマルチノード構成でこの問題が発生するため (バランサーがセッション アフィニティを実装しない限り)、carrierwave のデフォルトが ./tmp にキャッシュされるのは非常にクレイジーです。

ここに私のモデルとコントローラーなどがあります: https://gist.github.com/3161569

次の形式でカスタム作業を行う必要があります。

  • 何があっても、投稿されたすべてのファイルを保存します
  • 投稿されたファイル ID を隠しフィールドに中継する
  • 保存時に、ファイルおよび/または以前にアップロードされた ID を探します
  • モデルの関連付けを行う

このアプローチは、「魔法」ではありませんが、次の素晴らしい副作用ももたらします。

  • バックグラウンドでジョブを実行して画像をサムネイル化するプロセスと、ユーザーが「送信」を押すたびに image_magick をスピンアップするプロセスが 1 つあります (これは重大DOSベクトルであり、特に heroku のようなメモリが制限されたホストでは)

  • 画像を s3 にバックグラウンドで 1 時間ごとなどに移行できます。アップロードには単に新しい URL が含まれます (この場合、コントローラーはこれに気付いた場合に永続的なリダイレクトを発行する必要があります)。開発、ステージングなどのためにデータベースにそれらを保持し、アップロードやビューのコードを変更することなく、いつでも一部またはすべてのアップロードを s3 に移行できるため、これは非常に便利です。

于 2012-07-23T01:24:32.063 に答える