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.