2010-10-29 21 views

Répondre

146

Voici un moyen simple:

Ensuite, il suffit:

user.picture_from_url "http://www.google.com/images/logos/ps_logo2.png" 
+0

J'avais besoin d'utiliser update_attribute pour une raison quelconque. –

+0

Simple et efficace. Merci mec. – goo

+7

Si vous devez utiliser 'update_attributes', renommez' picture_from_url' en 'picture_url = (valeur)' par exemple. –

15

Téléchargez d'abord l'image avec la gemme curb sur un TempFile, puis affectez simplement l'objet tempfile et enregistrez votre modèle.

+2

Je ne vois pas ce qui ne va pas avec cette réponse, votant parce que je vois un vote négatif. – jpemberthy

+0

C'est la réponse la plus performante ([de loin] (http://toevolve.org/2011/04/03/http-request-performance.html)).Je ne suis pas vraiment un geek de la performance, mais cela s'additionne si vous travaillez avec de gros fichiers. – Chip

2

C'est une méthode hardcore:

original_url = url.gsub(/\?.*$/, '') 
filename = original_url.gsub(/^.*\//, '') 
extension = File.extname(filename) 

temp_images = Magick::Image.from_blob open(url).read 
temp_images[0].write(url = "/tmp/#{Uuid.uuid}#{extension}") 

self.file = File.open(url) 

où Uuid.uuid fait juste une pièce d'identité au hasard.

2

Cela peut vous être utile. Voici le code utilisant un trombone et une image présente dans une URL distante.

require 'rubygems' 
require 'open-uri' 
require 'paperclip' 
model.update_attribute(:photo,open(website_vehicle.image_url)) 

Dans le modèle

class Model < ActiveRecord::Base 
    has_attached_file :photo, :styles => { :small => "150x150>", :thumb => "75x75>" } 
end 
185

Dans Paperclip 3.1.4 il est devenu encore plus simple.

def picture_from_url(url) 
    self.picture = URI.parse(url) 
end 

C'est légèrement mieux qu'ouvert (url). Parce qu'avec open (url) vous allez obtenir "stringio.txt" comme nom de fichier. Avec ce qui précède, vous obtiendrez un nom propre du fichier basé sur l'URL. à savoir

self.picture = URI.parse("http://something.com/blah/avatar.png") 

self.picture_file_name # => "avatar.png" 
self.picture_content_type # => "image/png" 
+0

Comment pouvez-vous obtenir ce travail si vous êtes derrière un proxy? – Sebastian

+3

De paperclip wiki: https://github.com/thoughtbot/paperclip/wiki/Attachment-downloaded-from-a-URL Je l'ai exécuté avec succès dans la console, l'application est en heroku. –

+3

FYI, pour les URLs S3, j'obtiens toujours 'application/octet_stream' comme' content_type'. –

3

Comme ce sont vieux réponse est voici une plus récente:

Ajouter une image URL à distance à votre contrôleur désiré dans la base de données

$ rails generate migration AddImageRemoteUrlToYour_Controller image_remote_url:string 
$ rake db:migrate 

Modifier votre modèle

attr_accessible :description, :image, :image_remote_url 
. 
. 
. 
def image_remote_url=(url_value) 
    self.image = URI.parse(url_value) unless url_value.blank? 
    super 
end 

* Dans Rails4, vous devez ajouter attr_accessible dans le Controller.

Mettez à jour votre formulaire, si vous permettez autre de télécharger une image à partir d'une URL

<%= f.input :image_remote_url, label: "Enter a URL" %> 
+0

à quoi sert le «super»? –

+0

La fonction 'super' est utilisée pour invoquer la méthode d'origine, la recherche du corps de la méthode commence dans la super classe de l'objet qui contient la méthode d'origine –

10

Il ne fonctionne pas pour moi jusqu'à ce que je « ouvert » pour URI analysable. une fois que j'ai ajouté "ouvert" cela a fonctionné!

def picture_from_url(url) 
    self.picture = URI.parse(url).open 
end 

Ma version 4.2.1 est paperclip

Avant l'ouvrir ne détecte pas le type de contenu à droite, parce qu'il était pas un fichier. Il dirait image_content_type: "binaire/octet-stream", et même si je l'écrase avec le bon type de contenu cela ne fonctionnerait pas.