Sauvegarder le fichier dans le Trombone n'a pas à être téléchargés directement par le biais d'un formulaire.
Je suis à l'aide d'un Trombone dans un projet d'enregistrer des fichiers à partir d'Url de webcrawler résultats. Je ne suis pas sûr de savoir comment vous obtenez des pièces jointes (sont-ils sur le système de fichiers local du serveur? Votre application est une application de messagerie comme GMail?) mais aussi longtemps que vous pouvez obtenir un fichier de flux (par l'intermédiaire de quelque chose comme open(URI.parse(crawl_result))
dans mon cas...), vous pouvez joindre le fichier à votre modèle de champ qui est marqué has_attached_file
.
Ce billet de blog sur Simple Téléchargement via l'URL avec un Trombone, m'a aidé à comprendre cela.
Car il apparaît maintenant le blog original n'est plus disponible - voici l'essentiel, c'tiré de la wayback machine:
Cet exemple montre une Photo du modèle qui a une Image en pièce jointe.
La technique que nous utilisons nécessite l'ajout d'une *_remote_url
(string) de la colonne de votre attachement, qui est utilisé pour stocker l'URL d'origine. Donc, dans ce cas, nous avons besoin d'ajouter une colonne" image_remote_url
les photos de la table.
# 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 de spécial n'est nécessaire 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, nous avons ajouter un text_field appelés :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 %>
La viande des choses est dans la Photo de modèle. Nous devons require open-uri
, ajouter un attr_accessor :image_url
, et ne la normale has_attached_file
trucs. Ensuite, nous ajoutons une before_validation
de rappel pour télécharger le fichier dans l' image_url
d'attribut (si fourni) et enregistrer l'URL d'origine en tant que image_remote_url
. Enfin, nous faisons validates_presence_of :image_remote_url
, ce qui nous permet de sauver de nombreuses exceptions qui peuvent être levées lorsque vous essayez 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 de la partie la plus dure dans le modèle, "téléchargement" un fichier via l'URL travaille de l'intérieur script/console:
$ 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">