0
votes

I have CarrierWave and the FileSizeValidator (https://gist.github.com/795665) working, but I have a problem when the validation fails.

Scenario 1: A user doesn't have a custom avatar uploaded yet, so I show the sites default avatar in their dashboard. The user tries to upload a new image with a file size that is too big. The validation fails like expected, but I can't show the sites default avatar because <% if @user.avatar_url(:thumb) %> is true due to CarrierWave having all the cached data in the @user.avatar.

Scenario 2: The only difference to the first scenario is that a user already has a custom avatar and is trying to update it to a new one. Here the same thing happens. I can't show the actual avatar of the user because CarrierWave has all the cached data stored in it.

Scenario 3: The FileSizeValidator passes, but the avatar_cache doesn't work.

What I am trying to accomplish:

User has the sites default avatar or a custom avatar, and when validation fails I want their current avatar (sites default or custom) to show (instead of the failed cached). I also want to keep the cached data from CarrierWave, in case the form submit fails due to another validation (lets say wrong password), so the user doesn't have to select the image again to upload. I want to use :avatar_cache for that.

So pretty much when I want the cache to show (other validation fails) it doesn't, and when I don't want it to show (carrier wave validation fails) it does.

models/user.rb

attr_accessible :username, :email, :password, :password_confirmation, :postcount, :last_activity_at, :role, :avatar, :remove_avatar, :remote_avatar_url, :avatar_cache
require 'file_size_validator'
mount_uploader :avatar, AvatarUploader
validates :avatar, :file_size => { :maximum => 512.kilobytes.to_i }

views/users/edit.html.erb

<% if @user.avatar_url(:thumb) %>
  <%= image_tag(@user.avatar_url(:thumb)) %>
<% else %>
  <%= image_tag('/assets/theme/avatar-blank.png') %>
<% end %>
<table>
  <% if @user.errors.messages[:avatar] %>
  <tr>
    <td colspan="2">
      <span class="error"><%= @user.errors.messages[:avatar].flatten.join %></span>
    </td>
  </tr>
  <% end %>
  <tr>
    <td style="padding-right: 20px;">Upload from your PC: </td>
    <td><input class="file optional" id="user_avatar" name="user[avatar]" type="file" /></td>
  </tr>
  <tr>
    <td>Upload from a URL: </td>
    <td>
      <input class="string url optional" id="user_remote_avatar_url" name="user[remote_avatar_url]" size="50" type="url" />
      <input class="hidden" id="user_avatar_cache" name="user[avatar_cache]" type="hidden" value="" />
    </td>
  </tr>
<% if @user.avatar_url(:thumb) %>
  <tr>
    <td>Or remove your avatar: </td>
    <td>
      <input type="checkbox" id="remove_avatar" name="user[remove_avatar]" />
    </td>
  </tr>
<% end %>

uploaders/avatar_uploader.rb

class AvatarUploader < CarrierWave::Uploader::Base

  include CarrierWave::RMagick

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :thumb do
    process :resize_to_limit => [120, 120]
  end
  version :mini_thumb do
    process :resize_to_limit => [50, 50]
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

end
1

1 Answers

0
votes

I figured out how to get rid of the /tmp file when the file size validation doesn't pass. You can reset the image to the one before.

@user.avatar = @user.avatar.retrieve_from_store!(@user.avatar.identifier)

I still haven't figured out why my avatar_cache doesn't work when a different validation fails, but I've put that on hold for now and will revisit later.