Question

Vous savez que sur certains sites lorsque vous êtes invité à télécharger, par exemple, un avatar, vous cliquez sur le bouton, sélectionnez votre fichier, puis cliquez sur OK, mais avant vous envoyer la page (comme en, aucun enregistrement est créé / mise à jour), un petit aperçu de l'image apparaît?

Comment pourrais-je accomplir cela en utilisant Paperclip Rails?

Les points bonus pour tous ceux qui peuvent me diriger vers un tutoriel ou quelque chose qui pourrait me dire comment faire une culture Javascript sur l'image avant d'enregistrer le disque.

Je n'ai pas été en mesure de trouver beaucoup sur Google sur le sujet ... merci pour l'aide!

Était-ce utile?

La solution

Ce genre de chose est problématique du point de vue Rails en raison de l'upload d'image façon de travailler. Une stratégie pour le faire fonctionner mieux est:

  • Faire un sous-forme de votre transfert d'image, en utilisant éventuellement SWFUpload pour le rendre plus simple.
  • Créer un modèle pour recevoir vos téléchargements qui comprend une clé d'accès aléatoire utilisé pour récupérer et lier. Paperclip gère le fichier joint.
  • Utilisez AJAX pour remplir votre formulaire principal en insérant un champ caché, ou potentiellement un élément case visible avec le UNIQUE_KEY approprié, lorsque le sous-formulaire se termine.

Un modèle typique ressemble à quelque chose comme ceci:

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

La raison du champ UNIQUE_KEY est que vous pouvez lier cela dans la forme d'un dossier potentiellement non enregistré. Il est avantageux d'utiliser le UNIQUE_KEY au lieu de id lors de la mise en URL, car il est difficile de dire si un utilisateur doit être en mesure de voir cette image ou pas quand il est téléchargé depuis l'utilisateur propriétaire ne peut pas encore être attribué.

Cela empêche aussi les gens curieux de modifier une sorte d'identité séquentielle, facilement devinable dans votre URL et de voir d'autres avatars qui ont été téléchargés.

Vous pouvez récupérer l'URL des vignettes redimensionnée finale pour l'Avatar comme tout modèle à ce stade.

Vous pouvez enlever facilement les paramètres de réception et retraduire aux numéros d'identification Avatar:

# 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

En tant que personnes télécharger et retélécharger les images, vous finirez par avoir un grand nombre d'enregistrements orphelins qui ne sont pas réellement utilisés partout. Il est simple d'écrire une tâche de râteau pour purger tous ces après un certain laps de temps raisonnable est passé. Par exemple:

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

Utilisation destroy_all devrait avoir pour effet de purger tout le matériel de Paperclip ainsi.

Autres conseils

J'ai trouvé la solution affichée utile, il vous suffit de modifier pour être un seul fichier (si vous faites télécharger un seul fichier):

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

Note: J'ai utilisé un modèle distinct pour paperclip, un modèle de téléchargement qui a l'attribut image. Vous pouvez ajouter un style à la balise aperçu de l'image pour formater la taille de l'image (sinon il sera la taille d'origine).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top