Rails: Paperclip & 预览?

18
在某些网站上,当你被要求上传头像等内容时,你点击按钮,选择文件,然后点击“确定”,但是在提交页面之前(也就是说,没有创建/更新记录),会出现一个小的图片预览?
我如何使用Rails的Paperclip 实现这一点?
如果有人能指向一个教程或其他可以告诉我如何在保存记录之前对图像进行JavaScript裁剪的东西,那么就可以额外得到积分。
我在Google上没有找到太多关于这个主题的信息... 谢谢帮助!
3个回答

19

从 Rails 的角度来看,这种事情可能会有问题,因为图片上传的方式存在难题。为了使其更好地工作,一种策略是:

  • 为您的图像上传制作子表单,可能使用 swfupload 使其更加流畅。
  • 创建一个模型以接收您的上传内容,包括用于检索和链接它的一些随机访问密钥。Paperclip 处理所附文件。
  • 使用 AJAX 通过插入隐藏字段或潜在的可见复选框元素来填充您的主表单,具有适当的 unique_key。

一个典型的模型看起来像这样:

class Avatar < ActiveRecord::Base
  has_attached_file :image
  # ... Additional Paperclip options here

  before_validation :assign_unique_key

  belongs_to :user

  def to_param
    self.unique_key
  end

protected
  def assign_unique_key
    return if (self.unique_key.present?)

    self.unique_key = Digest::SHA1.hexdigest(ActiveSupport::SecureRandom.random_number(1<<512).to_s)
  end
end

unique_key字段的作用是为了将一个潜在未保存记录的表单与之关联。在将其放入URL时,使用unique_key比使用id更有优势,因为当用户上传图片时,很难确定用户是否应该能够看到此图片,因为所有者用户可能尚未被分配。

这也可以防止好奇的人更改URL中某种顺序、容易猜测的ID,并查看已上传的其他头像。

您可以像任何模型一样获取Avatar的最终缩略图URL。

在接收到参数后,您可以轻松地剥离它们并将其转换回Avatar ID号码:

# If an avatar_id parameter has been assigned...
if (params[:user][:avatar_id])
  # ...resolve this as if it were a unique_key value...
  avatar = Avatar.find_by_unique_key(params[:user][:avatar_id])
  # ...and repopulate the parameters if it has been found.
  params[:user][:avatar_id] = (avatar && avatar.id)
end

# ... params[:user] used as required for create or update

随着人们上传和重新上传图片,你最终会有大量的孤儿记录,这些记录实际上并没有在任何地方使用。编写一个 rake 任务来在合理的时间后清除所有这些记录非常简单。例如:

task :purge_orphan_avatars => :environment do
  # Clear out any Avatar records that have not been assigned to a particular
  # user within the span of two days.
  Avatar.destroy_all([ 'created_at<? AND user_id IS NULL', 2.days.ago ])
end

使用destroy_all方法应该会将所有的Paperclip相关内容全部清除。


5

我发现这里发布的解决方案很有用,如果你只上传单个文件,你只需要将其修改为仅上传一个文件即可:

<%= image_tag @upload.image, id:"something_unique"%>
<div class="row">
  <%= form_for @upload, :html => { :multipart => true } do |f| %>
    <%= f.file_field :image, id:"something_else_unique" %>
    <%= f.submit "Add photo" %>
  <% end %>
</div>

<script>
  function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object
      f=files[0]
      // Only process image files.
      if (f.type.match('image.*')) {
        var reader = new FileReader();
        reader.onload = (function(theFile) {
          return function(e) {
            // alert(e.target.result);
            document.getElementById("something_unique").src=e.target.result;
          };
        })(f);

      // Read in the image file as a data URL.
      reader.readAsDataURL(f);
      }
    }
  document.getElementById('something_else_unique').addEventListener('change', handleFileSelect, false);
</script>

注意:我使用了一个单独的模型来处理Paperclip,即上传模型,该模型具有图像属性。您可以为图像预览标签添加样式以格式化图片大小(否则它将是原始大小)。



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接