Як я можу завантажити файл з URL-адреси та зберегти його в Rails?


197

У мене є URL-адреса до зображення, яке я хочу зберегти локально, щоб я міг використовувати Paperclip для створення мініатюр для моєї програми. Який найкращий спосіб завантажити та зберегти зображення? (Я переглянув обробку рубінових файлів, але нічого не натрапив.)

Відповіді:


315

Спробуйте це:

require 'open-uri'
open('image.png', 'wb') do |file|
  file << open('http://example.com/image.png').read
end

1
Це працює. Дякую. Я спробував це на зображенні. Зображення було неправильно записано у файл. Наче воно зіпсувалося чи щось. Також ви можете мені вказувати це робити в додатку Rails. Чи можу я використовувати це в додатку Rails?
Алок Суейн

Так, ви можете використовувати його в додатку для рейок. Неправильно записаний файл - це, мабуть, тому, що я забув відкрити призначення у бінарному режимі запису. Я зараз це відредагую.
Леві

78
Це читає весь файл у пам'яті. Найкращий спосібIO.copy_stream(open('http://example.com/image.png'), 'destination.png')
janko-m

3
rails 5, 2016, мені не потрібно було require 'open-uri', просто використав код під ним
Mirror318

1
ця відповідь не спрацювала для мене. правильна відповідь тут: stackoverflow.com/a/29743394/1536309
Блер Андерсон

147

Ще коротша версія:

require 'open-uri'
download = open('http://example.com/image.png')
IO.copy_stream(download, '~/image.png')

Щоб зберегти те саме ім’я файлу:

IO.copy_stream(download, "~/#{download.base_uri.to_s.split('/')[-1]}")

2
І ефективніше, оскільки вихід не зберігається як рядок у пам'яті. +1
Ітай Грудев

2
Хоча насправді корисно, якщо відображаються обидві відповіді, тож такі, як я, можуть бачити обидва, подумати над різницями, а потім вибирати цю відповідь свідомо з правильних причин :)
Максвелл Еванс

30

Якщо ви використовуєте PaperClip, завантаження з URL-адреси тепер обробляється автоматично.

Якщо припустити, що у вас є щось на кшталт:

class MyModel < ActiveRecord::Base
  has_attached_file :image, ...
end

У вашій моделі просто вкажіть зображення як URL-адресу, щось подібне (написане навмисно від руки):

@my_model = MyModel.new
image_url = params[:image_url]
@my_model.image = URI.parse(image_url)

Напевно, ви захочете поставити це методом у вашій моделі. Це також буде добре працювати з тимчасовою файловою системою Heroku.

Скріпка буде брати звідти.

джерело: документація на скріпки


4
Для майбутніх пошукових записів
Alex Dunae

14

Я думаю, що це найясніший спосіб:

require 'open-uri'

File.write 'image.png', open('http://example.com/image.png').read

шавлія Я новачок в рейки, де я можу додати цей код в моделі або контролері або вид
Adarsh

1
Це залежить, але зазвичай ви робите щось подібне всередині моделі чи методу контролера. У контексті Rails вам, швидше за все, краще використовувати такі інструменти рамки, як ActiveStorage, а не писати безпосередньо на диск.
Мудрець Росс

10

Перевірте Net :: HTTP у стандартній бібліотеці. Документація містить кілька прикладів того, як завантажувати документи за допомогою HTTP.


2
Ця відповідь потребує більшої наочності, оскільки Kernel#openдає змогу не тільки отримати доступ до файлів, але й обробити виклик за допомогою префіксації символу труби (наприклад, open("| ls")). Таким чином, це може призвести до серйозного ризику безпеки, використовуючи змінний вхід до аргументу Kernel#open.
ConorB
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.