导轨:回形针&预览?

时间:2010-02-09 19:43:28

标签: ruby-on-rails paperclip

你知道在某些网站上当你被要求上传一个头像时,你点击按钮,选择你的文件,然后点击确定,但之前你提交页面(如在,没有创建/更新记录),图像的一些预览显示?

如何使用Paperclip为Rails完成此操作?

任何可以指导我指导教程或可能告诉我如何在保存记录之前对图像进行Javascript裁剪的人的奖励积分。

我无法在Google上找到关于此主题的更多内容...感谢您的帮助!

3 个答案:

答案 0 :(得分: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是有利的,因为很难判断用户是否应该能够在上传时查看此图片,因为可能尚未分配所有者用户。

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

您可以检索“头像”的最终调整大小的缩略图网址,就像此时的任何模型一样。

您可以在收到时轻松删除参数并转换回头像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材料。

答案 1 :(得分:5)

我发现发布的here解决方案非常有用,您只需将其修改为只有一个文件(如果您正在进行单个文件上传):

<%= 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使用了一个单独的模型,这是一个具有image属性的上传模型。您可以为图像预览标记添加样式以格式化图片大小(否则它将是原始大小)。

答案 2 :(得分:0)