2011-12-29 13 views
3

添付ファイル付きのメッセージを送信するフォームがあります。ユーザーは検証が RailsとPaperclipによる添付ファイルと処理の検証エラー

  • ユーザーがアップロードする必要がなかったので、メッセージを入力するのを忘れ
    • ユーザーを選択したファイルは
    • を押して提出すると、すべてのファイルがアップロードされるまで(長時間)待た添付するすべてのファイルをもう一度(長時間)

    既にアップロードされたファイルを覚えておくための簡単な方法はありますか? (ペーパークリップを使用しています)

  • 答えて

    1

    Messageオブジェクトを最初に作成し、ファイルのアップロードを開始してからフォームを使用してメッセージオブジェクトを更新するPUTリクエストを発行すると、最初はデフォルト(渡し)の値になります。

    この方法では、オブジェクトは作成時に有効ですが、唯一検証するのは更新情報も有効であることです(そうでない場合、メッセージはデフォルト値になり、ユーザーはファイルを再アップロードする必要があります)。

    Railsの移行を介してデータベース属性を設定して、デフォルトの値に設定できるため、コントローラでこれを行う必要はありません。

    change_column_default(:messages, :content, "You have a new message!") 
    
    +0

    これは良いアイデアです。私が現時点でやっていることは、レコードが無効な場合にも検証なしで強制的に保存することですが、もっと単純なものがあるかどうか疑問に思っていました。たとえば、データが有効でない場合、フォームにはすでに入力済みのデータが事前に入力されている、自然な動作のようなものがあります。 – Lucamug

    +0

    アップロードしたファイルをキャッシュに保存するには、CarrierWaveに切り替える必要があります。 Paperclipは、すでにアップロードされたファイルを検証エラーの間に保持することができないため、ユーザーはそれをもう一度アップロードする必要があります。 Paperclipを使い続けたいと思っているなら、上記のような設定をすることをお勧めします。 – iwasrobbed

    +0

    個人的には、私はCarrierWaveを使用しています。セットアップはかなり簡単です。現在の設定を切り替える場合は、余分な作業です。また、(すでにアップロードされたファイルの)キャッシュ機能は、読み込み専用のファイルシステムを持っているため、Herokuでは機能しません。 – iwasrobbed

    0

    これは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: ''} 
    
    +0

    それは、ペーパークリップの行為が行われたと言います。 if logo.staged? - >未定義のメソッド 'staged? ' # mariomol

    関連する問題