添付ファイル付きのメッセージを送信するフォームがあります。ユーザーは検証が RailsとPaperclipによる添付ファイルと処理の検証エラー
- ユーザーを選択したファイルは
- を押して提出すると、すべてのファイルがアップロードされるまで(長時間)待た添付するすべてのファイルをもう一度(長時間)
既にアップロードされたファイルを覚えておくための簡単な方法はありますか? (ペーパークリップを使用しています)
添付ファイル付きのメッセージを送信するフォームがあります。ユーザーは検証が RailsとPaperclipによる添付ファイルと処理の検証エラー
既にアップロードされたファイルを覚えておくための簡単な方法はありますか? (ペーパークリップを使用しています)
Message
オブジェクトを最初に作成し、ファイルのアップロードを開始してからフォームを使用してメッセージオブジェクトを更新するPUTリクエストを発行すると、最初はデフォルト(渡し)の値になります。
この方法では、オブジェクトは作成時に有効ですが、唯一検証するのは更新情報も有効であることです(そうでない場合、メッセージはデフォルト値になり、ユーザーはファイルを再アップロードする必要があります)。
Railsの移行を介してデータベース属性を設定して、デフォルトの値に設定できるため、コントローラでこれを行う必要はありません。
change_column_default(:messages, :content, "You have a new message!")
これはPaperClipを使用している最近のプロジェクトで修正する必要がありました。ちょっとハッキリですが、うまくいきます。モデルのafter_validationとbefore_saveを使用してcache_images()を呼び出そうとしましたが、何らかの理由で作成が失敗して、コントローラから呼び出すことができません。うまくいけば、これは誰か他の人に時間を節約するでしょう!
モデル:
class Shop < ActiveRecord::Base
attr_accessor :logo_cache
has_attached_file :logo
def cache_images
if logo.staged?
if invalid?
FileUtils.cp(logo.queued_for_write[:original].path, logo.path(:original))
@logo_cache = encrypt(logo.path(:original))
end
else
if @logo_cache.present?
File.open(decrypt(@logo_cache)) {|f| assign_attributes(logo: f)}
end
end
end
private
def decrypt(data)
return '' unless data.present?
cipher = build_cipher(:decrypt, 'mypassword')
cipher.update(Base64.urlsafe_decode64(data).unpack('m')[0]) + cipher.final
end
def encrypt(data)
return '' unless data.present?
cipher = build_cipher(:encrypt, 'mypassword')
Base64.urlsafe_encode64([cipher.update(data) + cipher.final].pack('m'))
end
def build_cipher(type, password)
cipher = OpenSSL::Cipher::Cipher.new('DES-EDE3-CBC').send(type)
cipher.pkcs5_keyivgen(password)
cipher
end
end
コントローラ:
def create
@shop = Shop.new(shop_params)
@shop.user = current_user
@shop.cache_images
if @shop.save
redirect_to account_path, notice: 'Shop created!'
else
render :new
end
end
def update
@shop = current_user.shop
@shop.assign_attributes(shop_params)
@shop.cache_images
if @shop.save
redirect_to account_path, notice: 'Shop updated.'
else
render :edit
end
end
ビュー:
= f.file_field :logo
= f.hidden_field :logo_cache
- if @shop.logo.file?
%img{src: @shop.logo.url, alt: ''}
それは、ペーパークリップの行為が行われたと言います。 if logo.staged? - >未定義のメソッド 'staged? ' #
これは良いアイデアです。私が現時点でやっていることは、レコードが無効な場合にも検証なしで強制的に保存することですが、もっと単純なものがあるかどうか疑問に思っていました。たとえば、データが有効でない場合、フォームにはすでに入力済みのデータが事前に入力されている、自然な動作のようなものがあります。 – Lucamug
アップロードしたファイルをキャッシュに保存するには、CarrierWaveに切り替える必要があります。 Paperclipは、すでにアップロードされたファイルを検証エラーの間に保持することができないため、ユーザーはそれをもう一度アップロードする必要があります。 Paperclipを使い続けたいと思っているなら、上記のような設定をすることをお勧めします。 – iwasrobbed
個人的には、私はCarrierWaveを使用しています。セットアップはかなり簡単です。現在の設定を切り替える場合は、余分な作業です。また、(すでにアップロードされたファイルの)キャッシュ機能は、読み込み専用のファイルシステムを持っているため、Herokuでは機能しません。 – iwasrobbed