Enregistrement de fichiers à l'aide Paperclip sans téléchargement
-
13-09-2019 - |
Question
J'ai eu une petite question. Est-il possible d'enregistrer un fichier sans téléchargement il fait via un formulaire?
Par exemple, disons que je regarde les pièces jointes des e-mails, et je veux les enregistrer à l'aide d'un trombone. Comment puis-je faire cela? Dois-je manuellement appeler un save_file (ou quelque chose de similaire) quelque part?
Toute aide serait grandement appréciée!
La solution
J'ai une tâche de râteau qui charge les images (logos client) à partir d'un répertoire directement sur parperclip. Vous pouvez probablement l'adapter à vos besoins.
Ceci est mon modèle simplifié du client:
class Client < ActiveRecord::Base
LOGO_STYLES = {
:original => ['1024x768>', :jpg],
:medium => ['256x192#', :jpg],
:small => ['128x96#', :jpg]
}
has_attached_file :logo,
:styles => Client::LOGO_STYLES,
:url => "/clients/logo/:id.jpg?style=:style"
attr_protected :logo_file_name, :logo_content_type, :logo_size
Puis sur ma tâche de coupe que je fais ceci:
# the logos are in a folder with path logos_dir
Dir.glob(File.join(logos_dir,'*')).each do |logo_path|
if File.basename(logo_path)[0]!= '.' and !File.directory? logo_path
client_code = File.basename(logo_path, '.*') #filename without extension
client = Client.find_by_code(client_code) #you could use the ids, too
raise "could not find client for client_code #{client_code}" if client.nil?
File.open(logo_path) do |f|
client.logo = f # just assign the logo attribute to a file
client.save
end #file gets closed automatically here
end
end
Cordialement!
Autres conseils
Le fichier enregistré dans Paperclip ne doit pas être téléchargé directement via un formulaire.
J'utilise Paperclip dans un projet pour enregistrer des fichiers à partir d'URL à partir des résultats de webcrawler. Je ne sais pas comment vous obtenez des pièces jointes (sont-ils sur le système de fichiers local du serveur? Est votre application une application e-mail comme GMail?), Mais aussi longtemps que vous pouvez obtenir un flux de fichiers (via quelque chose comme open(URI.parse(crawl_result))
dans mon cas ...) vous pouvez joindre ce fichier sur votre champ de modèle qui a marqué has_attached_file
.
Ce blog sur Easy Upload via l'URL avec Paperclip m'a aidé à comprendre cela.
Comme il apparaît maintenant le message blog n'est plus disponible - est ici l'essentiel de celui-ci tiré de la machine à remonter le temps:
Cet exemple montre un modèle de photo qui a une image en pièce jointe.
La technique que nous utilisons nécessite l'ajout d'une colonne de *_remote_url
(chaîne) pour votre attachement, qui est utilisé pour stocker l'URL d'origine. Donc, dans ce cas, nous devons ajouter une colonne nommée image_remote_url
la table de photos.
# db/migrate/20081210200032_add_image_remote_url_to_photos.rb
class AddImageRemoteUrlToPhotos < ActiveRecord::Migration
def self.up
add_column :photos, :image_remote_url, :string
end
def self.down
remove_column :photos, :image_remote_url
end
end
Rien ne doit spécial pour le contrôleur ...
# app/controllers/photos_controller.rb
class PhotosController < ApplicationController
def create
@photo = Photo.new(params[:photo])
if @photo.save
redirect_to photos_path
else
render :action => 'new'
end
end
end
Dans la forme, on ajoute un text_field appelé :image_url
, afin que les gens peuvent télécharger un fichier ou fournir une URL ...
# app/views/photos/new.html.erb
<%= error_messages_for :photo %>
<% form_for :photo, :html => { :multipart => true } do |f| %>
Upload a photo: <%= f.file_field :image %><br>
...or provide a URL: <%= f.text_field :image_url %><br>
<%= f.submit 'Submit' %>
<% end %>
Les choses charnue est dans le modèle photo. Nous devons require open-uri
, ajouter un attr_accessor :image_url
, et faire les choses de has_attached_file
normal. Ensuite, nous ajoutons un rappel before_validation
pour télécharger le fichier dans l'attribut image_url
(le cas échéant) et enregistrez l'URL d'origine comme image_remote_url
. Enfin, nous faisons validates_presence_of :image_remote_url
, ce qui nous permet de sauver des nombreuses exceptions qui peuvent être soulevées lors d'une tentative de télécharger le fichier.
# app/models/photo.rb
require 'open-uri'
class Photo < ActiveRecord::Base
attr_accessor :image_url
has_attached_file :image # etc...
before_validation :download_remote_image, :if => :image_url_provided?
validates_presence_of :image_remote_url, :if => :image_url_provided?, :message => 'is invalid or inaccessible'
private
def image_url_provided?
!self.image_url.blank?
end
def download_remote_image
self.image = do_download_remote_image
self.image_remote_url = image_url
end
def do_download_remote_image
io = open(URI.parse(image_url))
def io.original_filename; base_uri.path.split('/').last; end
io.original_filename.blank? ? nil : io
rescue # catch url errors with validations instead of exceptions (Errno::ENOENT, OpenURI::HTTPError, etc...)
end
end
Tout fonctionne normalement, y compris la création de vignettes, etc. De plus, puisque nous faisons tous les trucs dur dans le modèle, « ajout » un fichier via l'URL fonctionne à partir de script / console ainsi:
$ script/console
Loading development environment (Rails 2.2.2)
>> Photo.new(:image_url => 'http://www.google.com/intl/en_ALL/images/logo.gif')
=> #<Photo image_file_name: "logo.gif", image_remote_url: "http://www.google.com/intl/en_ALL/images/logo.gif">