CarrierWave と FileSizeValidator (https://gist.github.com/795665) が動作していますが、検証が失敗すると問題が発生します。
シナリオ 1: ユーザーはカスタム アバターをまだアップロードしていないため、サイトのデフォルトのアバターをダッシュボードに表示します。ユーザーが、ファイル サイズが大きすぎる新しい画像をアップロードしようとしました。検証は期待どおりに失敗しますが、<% if @user.avatar_url(:thumb) %>
CarrierWave がキャッシュされたすべてのデータを@user.avatar
.
シナリオ 2: 最初のシナリオとの唯一の違いは、ユーザーが既にカスタム アバターを持っていて、それを新しいものに更新しようとしていることです。ここでも同じことが起こります。CarrierWave にはすべてのキャッシュ データが保存されているため、ユーザーの実際のアバターを表示できません。
シナリオ 3: FileSizeValidator はパスしますが、avatar_cache
機能しません。
私が達成しようとしていること:
ユーザーにはサイトのデフォルトのアバターまたはカスタムアバターがあり、検証が失敗した場合、現在のアバター (サイトのデフォルトまたはカスタム) を (失敗したキャッシュの代わりに) 表示する必要があります。また、別の検証 (間違ったパスワードなど) が原因でフォームの送信が失敗した場合に備えて、CarrierWave からキャッシュされたデータを保持したいので、ユーザーはアップロードするために画像を再度選択する必要がありません。そのために使いたい:avatar_cache
。
そのため、ほとんどの場合、キャッシュを表示したい場合 (他の検証が失敗した場合) は表示されず、表示したくない場合 (搬送波の検証が失敗した場合) は表示されます。
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 }
ビュー/ユーザー/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 %>
アップローダー/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