Пожалуйста, предложите мне способ сохранить изображение с URL-адреса с помощью скрепки.
Сохранить изображение из URL-адреса скрепкой
Ответы (8)
Вот простой способ:
require "open-uri"
class User < ActiveRecord::Base
has_attached_file :picture
def picture_from_url(url)
self.picture = open(url)
end
end
Тогда просто:
user.picture_from_url "http://www.google.com/images/logos/ps_logo2.png"
update_attributes
, переименуйте picture_from_url
в picture_url=(value)
.
- person Daniel Rikowski; 02.06.2013
user.picture_from_url('/etc/password')
. Хотя, вероятно, в большинстве ситуаций это нормально.
- person David Tuite; 11.10.2013
open(url)
имя файла не является точным, например open-uri20150106-10034-lpd5fm.
вместо ef3a601e_ef3d008b_ef3d0f7e.jpg
.
- person Joshua Pinter; 06.01.2015
URI.parse(url)
вместо open(url)
- person Simon Franzen; 23.01.2019
В Paperclip 3.1.4 это стало еще проще.
def picture_from_url(url)
self.picture = URI.parse(url)
end
Это немного лучше, чем open (url). Потому что с open (url) вы получите "stringio.txt" в качестве имени файла. С помощью приведенного выше вы получите собственное имя файла на основе URL-адреса. т.е.
self.picture = URI.parse("http://something.com/blah/avatar.png")
self.picture_file_name # => "avatar.png"
self.picture_content_type # => "image/png"
application/octet_stream
как content_type
.
- person Joshua Pinter; 06.01.2015
У меня это не сработало, пока я не использовал "open" для разобранного URI. как только я добавил "открыть", все заработало!
def picture_from_url(url)
self.picture = URI.parse(url).open
end
Моя версия скрепки - 4.2.1
Перед открытием он не мог правильно определить тип содержимого, потому что это не был файл. Он сказал бы image_content_type: "binary / octet-stream", и даже если бы я заменил его правильным типом содержимого, это не сработало бы.
Сначала загрузите изображение с гемом curb
в TempFile
, а затем просто назначьте объект временного файла и сохраните свою модель.
В официальной документации сообщается здесь https://github.com/gotitbot/paperclip/wiki/Attachment-downloaded-from-a-URL
В любом случае он кажется не обновленным, потому что в последней версии скрепки что-то изменилось, и эта строка кода больше не действительна:
user.picture = URI.parse(url)
Это вызывает ошибку, в частности, возникает эта ошибка:
Paperclip::AdapterRegistry::NoHandlerError: No handler found for #<URI:: ...
Новый правильный синтаксис:
url = "https://www.example.com/photo.jpeg"
user.picture = Paperclip.io_adapters.for(URI.parse(url).to_s, { hash_digest: Digest::MD5 })
Также нам нужно добавить эти строки в файл config / initializers / paperclip.rb:
Paperclip::DataUriAdapter.register
Paperclip::HttpUrlProxyAdapter.register
Протестировал это с версией скрепки 5.3.0
, и она работает.
Это может быть вам полезно. Вот код с использованием скрепки и изображения в удаленном URL-адресе.
require 'rubygems'
require 'open-uri'
require 'paperclip'
model.update_attribute(:photo,open(website_vehicle.image_url))
В модели
class Model < ActiveRecord::Base
has_attached_file :photo, :styles => { :small => "150x150>", :thumb => "75x75>" }
end
Поскольку это старый ответ, вот новый:
Добавьте URL-адрес удаленного изображения к желаемому контроллеру в базе данных
$ rails generate migration AddImageRemoteUrlToYour_Controller image_remote_url:string
$ rake db:migrate
Измените свою модель
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
* В Rails4 вам нужно добавить attr_accessible в Контроллер.
Обновите форму, если вы разрешаете другим пользователям загружать изображение с URL-адреса
<%= f.input :image_remote_url, label: "Enter a URL" %>
super
?
- person Terence Chow; 26.08.2014
super
используется для вызова исходного метода, поиск тела метода начинается в суперклассе объекта, который, как было обнаружено, содержит исходный метод.
- person Mini John; 27.08.2014
Это хардкорный метод:
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)
где Uuid.uuid просто создает случайный идентификатор.