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 애플리케이션에서 사용할 수 있습니까?
Alok Swain

예, 레일 애플리케이션에서 사용할 수 있습니다. 파일이 제대로 작성되지 않은 것은 아마도 쓰기 바이너리 모드에서 대상을 여는 것을 잊었 기 때문일 것입니다. 지금 편집하겠습니다.
Levi

78
메모리에서 전체 파일을 읽습니다. 가장 좋은 방법은IO.copy_stream(open('http://example.com/image.png'), 'destination.png')
janko-m

3
2016 년 5 월 5 일, 난 필요가 없었습니다 require 'open-uri', 그냥 그 코드를 사용했습니다
Mirror318

1
이 답변은 저에게 효과적이지 않았습니다. 정답은 여기에 있습니다 : stackoverflow.com/a/29743394/1536309
Blair Anderson

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
Itay Grudev 2016 년

2
실제로 두 답변을 모두 표시하는 것이 유용하지만 나와 같은 사람들이 두 가지를 모두보고 차이점을 생각한 다음 올바른 이유로이 답변을 의식적으로 선택하십시오.)
Maxwell Evans

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
미래의 검색 자들을 위해 Paperclip은 더 이상 기본적으로 이것을 허용하지 않습니다 : medium.com/in-the-weeds/…
Alex Dunae

14

이것이 가장 명확한 방법이라고 생각합니다.

require 'open-uri'

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

sage 난 레일에
익숙하지 않아

1
모델에 따라 다르지만 일반적으로 모델 또는 컨트롤러 메서드 내에서 이와 같은 작업을 수행합니다. Rails 환경에서는 디스크에 직접 쓰는 것이 아니라 ActiveStorage와 같은 프레임 워크 도구를 사용하는 것이 좋습니다.
Sage Ross

10

표준 라이브러리에서 Net :: HTTP 를 확인하십시오 . 이 문서는 HTTP를 사용하여 문서를 다운로드하는 방법에 대한 몇 가지 예를 제공합니다.


2
이 답변 Kernel#open에는 파일 액세스뿐만 아니라 파이프 기호 (예 :)를 접두어로 사용하여 프로세스를 호출 할 수 있으므로 더 많은 가시성이 필요합니다 open("| ls"). 따라서의 인수에 변수 입력을 사용하면 심각한 보안 위험이 발생할 수 있습니다 Kernel#open.
ConorB
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.