I had to fix this in a recent project. This is a bit of hacks, but it works. I tried calling cache_images () using after_validation and before_save in the model, but it cannot be created for some reason that I cannot determine, so I just call it from the controller. Hope this helps someone else for a while!
Model:
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
controller:
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
View:
= f.file_field :logo = f.hidden_field :logo_cache - if @shop.logo.file? %img{src: @shop.logo.url, alt: ''}
source share