[refile][heroku]refileを使った本番環境での画像投稿機能[AWS][s3]

#はじめに
refileを使って、画像投稿機能を作って、herokuにデプロイして、オリジナルサービス完成！
と思ってたら、思わぬことに。
なぜか投稿した画像が一定時間過ぎると見れなくなる。　とか
パソコンでは見れるのに、iPhoneで画像が見れない。
という問題に直面しました。ので、その状況に陥ったときの対処方法を今回は書いていきます。

#そもそも
herokuにアップした画像は一定時間しか保存してくれないとのこと（どっかの記事で見ました）。
なので、どこかに保存する場所を作ってあげないといけない。そこで見つけたのが、AWSのs３という機能（？）。
s３のバケットというところに保存すればこの問題は解決しました。
ちょっと長くなりますが、方法をまとめていきたいと思います。

#どうするか
細かく伝えいきますので、順にやっていってください。

##gemの追加
refileには、AWSのs３と連携してくれる便利なgemがあります。それがこれ↓です。[(refile/github)](https://github.com/refile/refile)

```ruby:Gemfile
gem "refile-s3"
```
これをGemfileに記述した後、　`$ bundle install` します。

##ファイルの追加
`config/initializers`の中に　`refile.rb`というファイルを作成します。
その後

```ruby:config/initializers/refile.rb
require "refile/s3"

aws = {
  access_key_id: "AWS_ACCESS_KEY_ID",
  secret_access_key: "AWS_SECRET_ACCESS_KEY",
  region: "リージョン",
  bucket: "バケット名",
}
Refile.cache = Refile::S3.new(prefix: "cache", **aws)
Refile.store = Refile::S3.new(prefix: "store", **aws)
```
これをまるっと書きます。
記載してある`"AWS_ACCESS_KEY_ID"`,`"AWS_SECRET_ACCESS_KEY"`,`リージョン`,`バケット名`はまだ置いといていいです。

##AWSのs３にバケットを作る
このバケットというところに画像を保存していくのですが、まずはAWSのアカウントを作らなくてなりません。
参考になった記事がこちら　→　[Railsでcarrierwaveを使ってAWS S3に画像をアップロードする手順を画像付きで説明する](https://qiita.com/junara/items/1899f23c091bcee3b058)

この記事のAWS/IAM ~ S3バケット作成まで進めてください。かなり分かりやすく、僕でも楽々できました！

**！注意！**
`作成途中で、アクセスキーとシークレットアクセスキーは後で使うので、どこか自分しかわからないところに控えておいてください。`

バケットができたら次です。

##config/initializers/refile.rb
ここに戻ってきます。
先ほど作成した`refile.rb`の中にあった `AWS_ACCESS_KEY_ID` と　`AWS_SECRET_ACCESS_KEY` ですが、
控えておいたアクセスキーとシークレットアクセスキーを入れることになります。
ただ、ここに直接は書かず、別のファイルに書いていきます。（書いてもいいのかもしれないけど。）
ひとまず、先ほどバケットを作った際にきめた `リージョン`　と　`バケット名`　を記述してください。
ちなみにリージョンを東京にした場合は　`ap-northeast-1`　と記述すればいいです。

```ruby:config/initializers/refile.rb
require "refile/s3"

aws = {
  access_key_id: "AWS_ACCESS_KEY_ID",
  secret_access_key: "AWS_SECRET_ACCESS_KEY",
  region: "リージョン", 　　←ここと
  bucket: "バケット名",　　←ここ
}
Refile.cache = Refile::S3.new(prefix: "cache", **aws)
Refile.store = Refile::S3.new(prefix: "store", **aws)
```

##gemの追加
次に環境変数というものを使うために　

```
gem 'dotenv-rails'
```
を追加し、 `$ bundle install`　します。
環境変数とはパスワードを公開しないための変数とのこと。（あまりわかっていません。）

そのあとホームディレクトリ直下（gemfileとかがあるところ）に、　`.env` というファイル名でファイルを作成します。
`dotenv`はこの `.env`というファイルの中に書いてあるデータを参照します。
なのでここで環境変数を定義していきます。 さきほど控えておいたキーをここに記述します。

```ruby:.env
AWS_ACCESS_KEY_ID = アクセスキー
AWS_SECRET_ACCESS_KEY = シークレットアクセスキー
```

記述が終わったら、　`.gitignore`に先ほどの `.env`を記述します。
これはgithubにデプロイしたときに誰にも見られたくない環境変数を隠すためのファイルです。

```ruby:.gitignore
/.env
```

##heroku
次にherokuに移動してください。作成したアプリを選択して、　`settings` →　`Config Vars`にある `Reveal Config Vars`　を押すと
KEY　と　VALUE　を追加する画面が出てきます。
ここで
KEYには　`AWS_ACCESS_KEY_ID`,　VALUEには　`アクセスキー`
KEYには　`AWS_SECRET_ACCESS_KEY`,　VALUEには　`シークレットアクセスキー`
の２つを記述してください。

##最後に
```
$ git add .
$ git commit -m ""
$ git push heroku master
$ heroku run rails db:migrate
$ heroku open
```
をして、デプロイできればOKです！
そのあと、画像投稿をしてみて先ほど作成したバケットを確認すると、投稿した画像がそこに入っていると思います！
お疲れ様でした！

#まとめ
ほんと、これをするためだけに丸2日くらいかかりました…。センスないのかなってめっちゃ思いました。
知らない言葉とか多いけど、やっていくうちに慣れると思うので、今はひたすらにいろんな事を吸収します。

とりあえずこの手順でやれば本番環境での画像投稿機能はつけられると思います！

#参考記事

- [【Ruby on Rails】GitHubに公開したくない変数や値を隠してpushする方法](https://qiita.com/noraworld/items/bfa80811c9e30b4474af)
- [RailsアプリケーションをHerokuで動かす時の環境変数設定方法](https://qiita.com/opiyo_taku/items/a753623a4a565424dfec)
- [Railsでcarrierwaveを使ってAWS S3に画像をアップロードする手順を画像付きで説明する](https://qiita.com/junara/items/1899f23c091bcee3b058)