を使用してファイルをアップロードして多段階フォームのコードを働いているこれはOPのために少し遅れるかもしれませんが、うまくいけば、これは誰かに役立ちます。アップロードした画像をユーザーのセッションに保存する必要がありました(また多段階のフォーム用)。私もRyanのRailscast #217で始まりましたが、それ以上の進化を遂げました。私の環境は、CarrierwaveとMiniMagickを使用するRuby 2のRails 4と、activerecord-session_storeでした(後で説明します)。
私はOPと私の両方が持っていた問題は、ユーザーのセッションにすべてのPOSTパラメータを追加しようとしていたことだと考えていますが、ファイルアップロードでは、パラメータの1つが実際のUploadedFileオブジェクトそのためには大きくなる。以下で説明するアプローチは、その問題に対するもう1つの解決策です。
免責事項:複雑なオブジェクトをユーザーのセッションに格納すること、レコード識別子やその他の識別子データ(イメージのパスなど)を格納して必要なときにそのデータを参照する方がよいことは理想的ではありません。このセッションとモデル/データベースのデータを同期させる(重要ではない)タスクと、デフォルトのRailsセッションストア(クッキーを使用する)の2つの主な理由は4kbに制限されています。
マイモデル(submission.rb):
class Submission < ActiveRecord::Base
mount_uploader :image_original, ImageUploader
# ...
end
コントローラ(submissions_controller.rb):
def create
# If the submission POST contains an image, set it as an instance variable,
# because we're going to remove it from the params
if params[:submission] && params[:submission][:image_original] && !params[:submission][:image_original].is_a?(String)
# Store the UploadedFile object as an instance variable
@image = params[:submission][:image_original]
# Remove the uploaded object from the submission POST params, since we
# don't want to merge the whole object into the user's session
params[:submission].delete(:image_original)
end
# Merge existing session with POST params
session[:submission_params].deep_merge!(params[:submission]) if params[:submission]
# Instantiate model from newly merged session/params
@submission = Submission.new(session[:submission_params])
# Increment the current step in the session form
@submission.current_step = session[:submission_step]
# ... other steps in the form
# After deep_merge, bring back the image
if @image
# This adds the image back to the Carrierwave mounted uploader (which
# re-runs any processing/versions specified in the uploader class):
@submission.image_original = @image
# The mounted uploader now has the image stored in the Carrierwave cache,
# and provides us with the cache identifier, which is what we will save
# in our session:
session[:submission_params][:image_original] = @submission.image_original_cache
session[:image_processed_cached] = @submission.image_original.url(:image_processed)
end
# ... other steps in the form
# If we're on the last step of the form, fetch the image and save the model
if @submission.last_step?
# Re-populate the Carrierwave uploader's cache with the cache identifier
# saved in the session
@submission.image_original_cache = session[:submission_params][:image_original]
# Save the model
@submission.save
# ... render/redirect_to ...
end
end
私のアップローダファイルのほとんどは、いくつかのカスタム処理と株式ました。
注:セッションを強化するために、データベースバックアップセッションストアを提供するv4のRailsコアから抽出された宝石であるactiverecord-session_storeを使用しています(4kbのセッション制限が増えます)。インストール手順については、the documentationに従ってください。しかし、私の場合は、設定して忘れてしまうのはかなり早くて痛いものでした。トラフィックの多いユーザーのための注意:残りのセッションレコードは宝石によってパージされていないように見えるので、十分なトラフィックが得られれば、このテーブルは未知数の行にバルーンする可能性があります。
実際にイメージファイルまたはマイクロソフトワードファイルをアップロードしていますか? –
アップロードする前にファイルタイプを検証する必要があります – AlphaB
'CarrierWave :: IntegrityError'をキャッチするか、エラーをスローしないように' store() 'メソッド(! –