外部サイトの画像をCarrierWave経由でS3にアップロードする

ユーザーがアップロードした画像をCarrierWaveを利用してS3にアップロードするようにしていた
提携先が持っている画像を1枚使ってもよいという連絡をもらったので、画像をダウンロードしてS3に保存することにした

## 提携先から画像URLを取得する
APIで取得できた
内容は割愛

## 画像URLから画像データのダウンロード
URLから画像をダウンロードする場合、よく出てくるのがopen-uri
```
image = open(image_url)
```

手軽にできるがリサイズとかはできなさそう
なので、MiniMagickを使う
```
tempfile = MiniMagick::Image.open(image_url)
```
MiniMagick::Imageのインスタンスが作成できた
これで画像の書き出しやリサイズができる
http://keruuweb.com/rails-minimagick%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/

```
# そのまま書き出し
tempfile.write

# 300x300にリサイズして書き出し
tempfile.resize(300x300)
tempfile.write
```

## ダウンロードした画像をCarrierWaveでS3にアップロード
CarrierWave
https://github.com/carrierwaveuploader/carrierwave
ユーザーがアップロードした画像はS3に保存する設定をしているので、ダウンロードしたファイルをユーザーがアップロードしたファイルと同等に扱えるようになればよい

ユーザーがアップロードした画像の型を確認すると
```
ActionDispatch::Http::UploadedFile
```
だった
このクラスのインスタンスを作成できればよさそう
少し調べてみると
[Rails Uploadedfileを手動で作る | このコードわからん](http://hai3.net/blog/2012/09/28/rails-create-uploadedfile/)
に記載されていた

```
file_path = File.join(Rails.root, 'path/to/file')

ActionDispatch::Http::UploadedFile.new(
  filename: File.basename(file_path),
  type: 'image/jpeg',
  tempfile: File.open(file_path)
)
```

これにならって
```
tempfile = MiniMagick::Image.open(image_url)
ActionDispatch::Http::UploadedFile.new(
  filename: File.basename(image_url),
  type: 'image/jpeg',
  tempfile: tempfile
)
```
とすることで、ユーザーがアップロードしたときと同じデータが作成できた
(ユーザーがアップロードした場合はheaderがセットされるがこの場合は必要なかった)

あとは、CarrierWaveの設定によってmodelにこのデータを保存してS3にアップロードできた

ポイント
ユーザーが画像をアップロードしたときと同じインスタンスを作成できればなんでもCarrierWave経由で保存が可能
関連書籍
Back