URL'den bir dosyayı nasıl indirebilir ve Rails'e nasıl kaydedebilirim?


197

Uygulamam için bir küçük resim oluşturmak için Paperclip'i kullanabilmem için yerel olarak kaydetmek istediğim bir görüntünün URL'si var. Görüntüyü indirmenin ve kaydetmenin en iyi yolu nedir? (Yakut dosya işleme içine baktım ama hiçbir şey rastlamadım.)

Yanıtlar:


316

Bunu dene:

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

1
Bu çalışıyor. Teşekkürler. Bunu bir görüntü üzerinde denedim. Görüntü dosyaya düzgün yazılmamış. Sanki bozulmuş ya da başka bir şey. Ayrıca bir Rails uygulamasında aynı şeyi yapmak için bana rehberlik edebilir. Bunu bir Rails uygulamasında kullanabilir miyim?
Alok Swain

Evet, raylar uygulamasında kullanabilirsiniz. Dosya düzgün yazılmamış olabilir, çünkü hedefi yazma-ikili modda açmayı unuttum. Bunu şimdi düzenleyeceğim.
Levi

78
Bu, bellekteki tüm dosyayı okur. En iyi yolIO.copy_stream(open('http://example.com/image.png'), 'destination.png')
janko-m

3
raylar 5, 2016, gerek yoktu require 'open-uri', sadece altındaki kodu kullandım
Mirror318

1
bu cevap benim için işe yaramadı. doğru cevap burada: stackoverflow.com/a/29743394/1536309
Blair Anderson

147

Daha da kısa bir versiyon:

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

Aynı dosya adını korumak için:

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

2
Ve çıkış bellekte dize olarak saklanmadığından daha verimlidir. +1
Itay Grudev

2
Her iki cevabın görüntülenmesi gerçekten yararlı olsa da, benim gibi insanlar her ikisini de görebilir, farklılıkları düşünebilir ve daha sonra bu cevabı bilinçli olarak doğru nedenlerle seçebilirler :)
Maxwell Evans

30

PaperClip kullanıyorsanız, bir URL'den indirme artık otomatik olarak yapılır.

Şöyle bir şeye sahip olduğunuzu varsayarsak:

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

Modelinizde, görüntüyü URL olarak belirtin, şöyle bir şey (kasıtlı uzun el ile yazılmış):

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

Muhtemelen bunu modelinizdeki bir yönteme koymak isteyeceksiniz. Bu aynı zamanda Heroku'nun geçici dosya sisteminde de işe yarayacaktır.

Ataç oradan alacak.

kaynak: ataç belgeleri


4
Gelecekteki araştırmacılar için, Paperclip artık varsayılan olarak buna izin vermiyor
Alex Dunae

14

Bence bu en açık yol:

require 'open-uri'

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

adaçayı ben raylar için yeni, nerede bu kodu model veya denetleyici veya görünüm ekleyebilirsiniz
adarsh

1
Bağlıdır, ancak tipik olarak bir model veya denetleyici yönteminde böyle bir şey yaparsınız. Rails bağlamında, doğrudan diske yazmak yerine, çerçevenin ActiveStorage gibi araçlarını kullanmanız daha iyi olur.
Sage Ross

10

Check out Net :: HTTP standart kütüphanede. Dokümantasyon, HTTP kullanarak dokümanların nasıl indirileceğine dair birkaç örnek sunmaktadır.


2
Bu yanıt Kernel#open, yalnızca dosya erişimini sağlamakla kalmayıp aynı zamanda bir boru sembolü (ör open("| ls").) Bu nedenle, argümanına değişken girdi kullanarak ciddi bir güvenlik riskine yol açabilir Kernel#open.
ConorB
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.