Rails: скрепка и превью? - PullRequest
       23

Rails: скрепка и превью?

18 голосов
/ 09 февраля 2010

Вы знаете, на некоторых сайтах, когда вас просят загрузить, скажем, аватар, вы нажимаете кнопку, выбираете свой файл, затем нажимаете OK, но за до вы отправляете страницу (как в , запись не создается / обновляется), появляется небольшой предварительный просмотр изображения?

Как бы я достиг этого, используя Скрепка для Rails?

Бонусные баллы для всех, кто может указать мне на учебник или что-то, что может сказать мне, как сделать обрезку Javascript на изображении перед сохранением записи.

Я не смог найти много в Google по этому вопросу ... спасибо за помощь!

Ответы [ 3 ]

19 голосов
/ 09 февраля 2010

Подобные вещи проблематичны с точки зрения Rails из-за способа загрузки изображений. Одна стратегия, чтобы заставить это работать лучше, является:

  • Создайте под-форму для загрузки вашего изображения, возможно, используя swfupload , чтобы сделать его более упорядоченным.
  • Создайте модель для получения ваших загрузок, которая включает в себя некоторый случайный ключ доступа, используемый для его получения и связывания. Скрепка обрабатывает прикрепленный файл.
  • Используйте 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 и видеть другие загруженные аватары.

Вы можете получить окончательный уменьшенный URL-адрес уменьшенного изображения для Аватара, как и для любой модели на этом этапе.

Вы можете легко убрать параметры при получении и перевести обратно на идентификационные номера Аватара:

# 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

По мере того, как люди загружают и повторно загружают изображения, в конечном итоге у вас будет большое количество потерянных записей, которые фактически нигде не используются. Очень просто написать грабли, чтобы очистить их после того, как прошло достаточно времени. Например:

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 голосов
/ 22 мая 2014

Я нашел решение, опубликованное здесь полезным, вам просто нужно изменить его, чтобы он был только одним файлом (если вы загружаете один файл):

<%= 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>

Примечание: я использовал отдельную модель для скрепки, модель загрузки с атрибутом изображения. Вы можете добавить стили к тегу предварительного просмотра изображения, чтобы отформатировать размер изображения (иначе это будет исходный размер).

0 голосов
/ 15 ноября 2012

Или вы можете использовать ajax и iframe http://www.html5rocks.com/en/tutorials/file/dndfiles/#toc-reading-files

...