35歳だけどRailsチュートリアルやってみた。[第4版 13章 13.4 マイクロポストの画像投稿 まとめ&解答例]

#はじめに
最近、プロジェクト管理業務が業務の大半を占めており、
プログラムを書く機会がなかなかありません。

このままだとプログラムがまったく書けない人になってしまう危機感（迫り来る35歳定年説）と、
新しいことに挑戦したいという思いから、
[Ruby on Rails チュートリアル実例を使ってRailsを学ぼう 第4版](https://railstutorial.jp/)を学習中です。
業務で使うのはもっぱらJavaなのですが、Rails楽しいですね。


これまでEvernoteに記録していましたが、ソースコードの貼付けに限界を感じたため、
Qiitaで自分が学習した結果をアウトプットしていきます。

個人の解答例なので、誤りがあればご指摘ください。

##動作環境
- cloud9
- ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
- Rails 5.0.0.1

##13.4 マイクロポストの画像投稿
###本章での学び
画像付きマイクロポストを投稿できるようにする。

##13.4.1 基本的な画像アップロード
###本章での学び
####【事前準備】CarrierWaveのインストール
画像アップローダーであるCarrierWaveをGemfileに追加する。
また、画像処理を行うmini_magickと、クラウド環境へアップロードするためのfogも追加する。

```/sample_app/Gemfile
gem 'carrierwave', '1.1.0'
gem 'mini_magick', '4.7.0'
gem 'fog', '1.40.0'
```

インストール。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies...
Using rake 12.0.0
Installing CFPropertyList 2.3.5
Using concurrent-ruby 1.0.5
Using i18n 0.8.1
Using minitest 5.10.1
Using thread_safe 0.3.6
Using builder 3.2.3
Using erubis 2.7.0
Using mini_portile2 2.1.0
Using rack 2.0.1
Using nio4r 1.2.1
Using websocket-extensions 0.1.2
Using mime-types-data 3.2016.0521
Using arel 7.1.4
Using ansi 1.5.0
Using execjs 2.7.0
Using bcrypt 3.1.11
Using sass 3.4.23
Using will_paginate 3.1.0
Using bundler 1.14.6
Using byebug 9.0.0
Using coderay 1.1.1
Using coffee-script-source 1.12.2
Using method_source 0.8.2
Using thor 0.19.4
Using debug_inspector 0.0.2
Installing excon 0.58.0
Using ffi 1.9.18
Using formatador 0.2.5
Using multi_json 1.12.1
Installing ipaddress 0.8.3
Installing xml-simple 1.1.5
Installing inflecto 0.0.2
Installing json 1.8.6 with native extensions
Installing trollop 2.1.2
Using rb-fsevent 0.9.8
Using lumberjack 1.0.11
Using nenv 0.3.0
Using shellany 0.0.1
Using slop 3.6.0
Using guard-compat 1.2.1
Installing mini_magick 4.7.0
Using ruby-progressbar 1.8.1
Using puma 3.4.0
Using tilt 2.0.6
Using spring 1.7.2
Using sqlite3 1.3.11
Using turbolinks-source 5.0.0
Installing fission 0.5.0
Using faker 1.6.6
Using tzinfo 1.2.2
Using nokogiri 1.7.0.1
Using rack-test 0.6.3
Using sprockets 3.7.1
Using websocket-driver 0.6.5
Using mime-types 3.1
Using autoprefixer-rails 6.7.7.1
Using uglifier 3.0.0
Using bootstrap-will_paginate 0.0.10
Using coffee-script 2.4.1
Using rb-inotify 0.9.8
Installing fog-core 1.45.0
Using notiffany 0.1.1
Using pry 0.10.4
Using guard-minitest 2.4.4
Using minitest-reporters 1.1.9
Using turbolinks 5.0.1
Using activesupport 5.0.0.1
Using loofah 2.0.3
Installing rbvmomi 1.11.3
Using mail 2.6.4
Using bootstrap-sass 3.3.6
Using listen 3.0.8
Installing fog-json 1.0.2
Installing fog-xml 0.1.3
Installing fog-local 0.3.1
Installing fog-vmfusion 0.1.0
Using rails-dom-testing 2.0.2
Using globalid 0.3.7
Using activemodel 5.0.0.1
Using jbuilder 2.4.1
Using rails-html-sanitizer 1.0.3
Installing fog-vsphere 1.11.3
Using guard 2.13.0
Using spring-watcher-listen 2.0.0
Installing fog-aliyun 0.2.0
Installing fog-brightbox 0.13.0
Installing fog-dnsimple 1.0.0
Installing fog-openstack 0.1.21
Installing fog-profitbricks 4.0.0
Installing fog-sakuracloud 1.7.5
Installing fog-serverlove 0.1.2
Installing fog-softlayer 1.1.4
Installing fog-storm_on_demand 0.1.1
Installing fog-atmos 0.1.0
Installing fog-aws 1.4.0
Installing fog-cloudatcost 0.1.2
Installing fog-digitalocean 0.3.0
Installing fog-dynect 0.0.3
Installing fog-ecloud 0.3.0
Installing fog-google 0.1.0
Installing fog-powerdns 0.1.1
Installing fog-rackspace 0.1.5
Installing fog-radosgw 0.0.5
Installing fog-riakcs 0.1.0
Installing fog-terremark 0.1.0
Installing fog-voxel 0.1.0
Installing fog-xenserver 0.3.0
Using activejob 5.0.0.1
Using activerecord 5.0.0.1
Installing carrierwave 1.1.0
Using actionview 5.0.0.1
Installing fog 1.40.0
Using actionpack 5.0.0.1
Using actioncable 5.0.0.1
Using actionmailer 5.0.0.1
Using railties 5.0.0.1
Using sprockets-rails 3.2.0
Using rails-controller-testing 0.1.1
Using coffee-rails 4.2.1
Using jquery-rails 4.1.1
Using web-console 3.1.1
Using rails 5.0.0.1
Using sass-rails 5.0.6
Bundle complete! 28 Gemfile dependencies, 124 gems now installed.
Gems in the group production were not installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from fog:
------------------------------
Thank you for installing fog!

IMPORTANT NOTICE:
If there's a metagem available for your cloud provider, e.g. `fog-aws`,
you should be using it instead of requiring the full fog collection to avoid
unnecessary dependencies.

'fog' should be required explicitly only if:
- The provider you use doesn't yet have a metagem available.
- You require Ruby 1.9.3 support.
------------------------------
```

####【事前準備】画像アップローダーの作成
Railsのジェネレーターで画像アップローダーを生成する。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ rails generate uploader Picture
Running via Spring preloader in process 9141
Expected string default value for '--jbuilder'; got true (boolean)
      create  app/uploaders/picture_uploader.rb
```

####【事前準備】DBのマイグレーション
自動生成したPictureとマイクロポストを関連付けるために、
Micropostモデルにpicture属性を追加する。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ rails generate migration add_picture_to_microposts picture:string
Running via Spring preloader in process 9155
Expected string default value for '--jbuilder'; got true (boolean)
      invoke  active_record
      create    db/migrate/20170820040443_add_picture_to_microposts.rb
```

自動生成されたマイグレーションファイル。

```/sample_app/db/migrate/20170820040443_add_picture_to_microposts.rb
class AddPictureToMicroposts < ActiveRecord::Migration[5.0]
  def change
    add_column :microposts, :picture, :string
  end
end
```

マイグレーションの実行。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ rails db:migrate
== 20170820040443 AddPictureToMicroposts: migrating ===========================
-- add_column(:microposts, :picture, :string)
   -> 0.0048s
== 20170820040443 AddPictureToMicroposts: migrated (0.0050s) ==================
```

####【model】Micropostモデルに画像を追加する
CarrierWaveに画像と関連付けたモデルを伝えるために、`mount_uploader`メソッドを使用する。引数に、属性名（今回はpicture）と、クラス名（PictureUploader）を指定する。

```/sample_app/app/models/micropost.rb
class Micropost < ApplicationRecord
  belongs_to :user
  default_scope -> { order(created_at: :desc) }
  mount_uploader :picture, PictureUploader
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 140 }
end
```

チュートリアルでは、この時点でのtestはgreenになると書かれているが、redになる。
（Micropostモデルから、`mount_uploader`メソッドを削除するとgreenになる）

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ rails test
Running via Spring preloader in process 9762
Started with run options --seed 39087

ERROR["test_profile_display", UsersProfileTest, 0.09379067993722856]
 test_profile_display#UsersProfileTest (0.09s)
NameError:         NameError: uninitialized constant Micropost::PictureUploader
            app/models/micropost.rb:4:in `<class:Micropost>'
            app/models/micropost.rb:1:in `<top (required)>'

 FAIL["test_content_should_be_at_most_140_characters", MicropostTest, 2.966606823960319]
 test_content_should_be_at_most_140_characters#MicropostTest (2.97s)
        Expected true to be nil or false
        test/models/micropost_test.rb:32:in `block in <class:MicropostTest>'

 FAIL["test_user_id_should_be_present", MicropostTest, 2.974773451918736]
 test_user_id_should_be_present#MicropostTest (2.97s)
        Expected true to be nil or false
        test/models/micropost_test.rb:22:in `block in <class:MicropostTest>'

 FAIL["test_content_should_be_present", MicropostTest, 2.9872157878708094]
 test_content_should_be_present#MicropostTest (2.99s)
        Expected true to be nil or false
        test/models/micropost_test.rb:27:in `block in <class:MicropostTest>'

 FAIL["test_micropost_interface", MicropostsInterfaceTest, 3.539895322872326]
 test_micropost_interface#MicropostsInterfaceTest (3.54s)
        "Micropost.count" didn't change by 0.
        Expected: 38
          Actual: 39
        test/integration/microposts_interface_test.rb:16:in `block in <class:MicropostsInterfaceTest>'

  59/59: [==================================================================================================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.68161s
59 tests, 245 assertions, 4 failures, 1 errors, 0 skips
```

一旦先に進めることにする。


####【view】パーシャルに画像を追加する。
`f.file_field`属性を使って、マイクロポスト投稿フォームに画像を表示する。

file_fieldは、ファイル選択ボックスを表示するとのこと。

[Railsドキュメント　file_field](http://railsdoc.com/references/file_field)

```/sample_app/app/views/shared/_micropost_form.html.erb
<%= form_for(@micropost) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-primary" %>
  <span class="picture">
    <%= f.file_field :picture %>
  </span>
<% end %>
```

####【controller】Micropostsコントローラのリファクタリング
picture属性をブラウザから更新できる許可リストに追加する。

```/sample_app/app/controllers/microposts_controller.rb
  private

    def micropost_params
      params.require(:micropost).permit(:content, :picture)
    end
```

####【view】マイクロポスト表示パーシャルのリファクタリング
`image_tag`ヘルパーを使って、マイクロポストの表示項目に画像を追加する。
画像が存在する場合のみ、画像を表示する。

image_tagヘルパーは以下参照。
[Railsドキュメント image_tag](http://railsdoc.com/references/image_tag)

```/sample_app/app/views/microposts/_micropost.html.erb
  <span class="content">
    <%= micropost.content %>
    <%= image_tag micropost.picture.url if micropost.picture? %>
  </span>
```

###演習1
*画像付きのマイクロポストを投稿してみましょう。もしかして、大きすぎる画像が表示されてしまいましたか? (心配しないでください、次の13.4.3でこの問題を直します)。*

画像がアップロードできることを確認。
![image](https://qiita-image-store.s3.amazonaws.com/0/98130/aa10d636-b196-d5ae-0844-d60aeaa4a9a3.png)

###演習2
*リスト 13.63に示すテンプレートを参考に、13.4で実装した画像アップローダーをテストしてください。テストの準備として、まずはサンプル画像をfixtureディレクトリに追加してください (コマンド例: cp app/assets/images/rails.png test/fixtures/)。リスト 13.63で追加したテストでは、Homeページにあるファイルアップロードと、投稿に成功した時に画像が表示されているかどうかをチェックしています。なお、テスト内にあるfixture_file_uploadというメソッドは、fixtureで定義されたファイルをアップロードする特別なメソッドです18。ヒント: picture属性が有効かどうかを確かめるときは、11.3.3で紹介したassignsメソッドを使ってください。このメソッドを使うと、投稿に成功した後にcreateアクション内のマイクロポストにアクセスするようになります。*

サンプル画像をfixtureディレクトリに配置する。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ cp app/assets/images/rails.png test/fixtures/
```

テストを追加する。

- HTML属性に、input type=file属性があることを確認
- fixtureディレクトリにあるrails.pngを、image/pngにアップロードして、picture変数に代入
- マイクロポスト投稿時に、picture変数を引数に追加して投稿できることを確認
- マイクロポストにpictureが存在することを確認

※しれっと、`params:`ハッシュがなくなっているので注意。

```/sample_app/test/integration/microposts_interface_test.rb
  test "micropost interface" do
    log_in_as(@user)
    get root_path
    assert_select 'div.pagination'
    assert_select 'input[type=file]'
    # 無効な送信
    assert_no_difference 'Micropost.count' do
      # post microposts_path params: { micropost: { content: "" } }
      post microposts_path micropost: { content: "" }
    end
    assert_select 'div#error_explanation'
    # 有効な送信
    content = "This micropost really ties the room together"
    picture = fixture_file_upload('test/fixtures/rails.png','image/png')
    assert_difference 'Micropost.count', 1 do
      # post microposts_path, params: { micropost: { content: content } }
      post microposts_path, micropost: { content: content, picture: picture }
    end
    assert @user.microposts.first.picture?
    follow_redirect!
    assert_match content, response.body
    # 投稿を削除する
    assert_select 'a', text: 'delete'
    micropost = @user.microposts.paginate(page: 1).first
    assert_difference 'Micropost.count', -1 do
      delete micropost_path(micropost)
    end
    # 違うユーザーのプロフィールにアクセス（削除リンクがないことを確認）
    get user_path(users(:archer))
    assert_select 'a', text: 'delete', count: 0
  end
```



##13.4.2 画像の検証
###本章での学び
画像サイズや拡張子に対するバリデーションを実装する。

####画像フォーマットのバリデーション追加
`extension_whitelist`メソッドのコメントアウトを外す。

```/sample_app/app/uploaders/picture_uploader.rb
  def extension_whitelist
    %w(jpg jpeg gif png)
  end
```

####【model】画像サイズのバリデーション追加
画像のサイズを制限する独自のバリデーションを追加する。
独自のバリデーションを定義するためには、`validates`メソッドではなく、`validate`メソッドを使用する。
5MBを超えた場合はエラーメッセージを表示する。

```/sample_app/app/models/micropost.rb
  validate  :picture_size
  
  private
  
    # アップロードされた画像サイズをバリデーションする
    def picture_size
      if picture.size > 5.megabytes
        errors.add(:picture, "should be less than 5MB")
      end
    end
```

####【view】パーシャルにファイルサイズチェックを追加する
マイクロポスト投稿フォームに、画像の拡張子の許可と、ファイルサイズチェックを行うjQuery関数を追加する。

jQuery関数では、ブラウザのインスペクタ機能でjavaScriptを直接修正したり、curlで直接POSTしてきた場合、防ぐことができない。そのために前項で実装したサーバサイド側のバリデーションも必要となる。

```/sample_app/app/views/shared/_micropost_form.html.erb
<%= form_for(@micropost) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-primary" %>
  <span class="picture">
    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png'%>
  </span>
<% end %>

<script type="text/javascript">
  $('#micropost_picture').bind('change', function() {
    var size_in_megabytes = this.files[0].size/1024/1024;
    if (size_in_megabytes > 5) {
      alert('Maximum file size is 5MB. Please choose a smaller file.')
    }
  });
</script>
```

###演習1
*5MB以上の画像ファイルを送信しようとした場合、どうなりますか?*

jQueryの警告が表示されアップロードできない。

![image](https://qiita-image-store.s3.amazonaws.com/0/98130/767f7534-4b14-2d07-af11-d5db2e37bc34.png)

###演習2
*無効な拡張子のファイルを送信しようとした場合、どうなりますか?*

ホワイトリストのエラーメッセージが表示される。

![image](https://qiita-image-store.s3.amazonaws.com/0/98130/be8fc879-6a58-0445-e454-15f5ba9feb8f.png)


##13.4.3 画像のリサイズ
###本章での学び
画像のリサイズ処理を実装する。

####【事前準備】ImageMagickのインストール
ImageMagickをインストールする。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ sudo apt-get update
yokoyan:~/workspace/sample_app (user-microposts) $ sudo apt-get install imagemagick --fix-missing
```

####アップローダーのリファクタリング
MiniMagickというImageMagickとRubyをつなぐgemを使って画像をリサイズする。
縦横どちらかが400pxを超えていた場合、適切なサイズにリサイズする。

```/sample_app/app/uploaders/picture_uploader.rb
class PictureUploader < CarrierWave::Uploader::Base

  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  include CarrierWave::MiniMagick
  process reseize_to_limit: [400, 400]
```


###演習1
*解像度の高い画像をアップロードし、リサイズされているかどうか確認してみましょう。画像が長方形だった場合、リサイズはうまく行われているでしょうか?*

上記の実装をした後、動作確認を行うと`translation missing: en.errors.messages.mini_magick_processing_error`エラーが発生する。
以下の人と同じ現象。未解決。

[Image translation missing: en.errors.messages.mini_magick_processing_error #2102](https://github.com/carrierwaveuploader/carrierwave/issues/2102)


###演習2
*既にリスト 13.63のテストを追加していた場合、この時点でテストスイートを走らせるとエラーメッセージが表示されるようになるはずです。このエラーを取り除いてみましょう。ヒント: リスト 13.68にある設定ファイルを修正し、テスト時はCarrierWaveに画像のリサイズをさせないようにしてみましょう。*

現時点でテストがredになることを確認。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ rails test
Running via Spring preloader in process 3120
Started with run options --seed 50042

DEPRECATION WARNING: ActionDispatch::IntegrationTest HTTP request methods will accept only=======================================================================                                ] 83% Time: 00:00:02,  ETA: 00:00:01
the following keyword arguments in future Rails versions:
params, headers, env, xhr, as

Examples:

get '/profile',
  params: { id: 1 },
  headers: { 'X-Extra-Header' => '123' },
  env: { 'action_dispatch.custom' => 'custom' },
  xhr: true,
  as: :json
 (called from block (2 levels) in <class:MicropostsInterfaceTest> at /home/ubuntu/workspace/sample_app/test/integration/microposts_interface_test.rb:27)
 FAIL["test_micropost_interface", MicropostsInterfaceTest, 2.907269152114168]
 test_micropost_interface#MicropostsInterfaceTest (2.91s)
        "Micropost.count" didn't change by 1.
        Expected: 39
          Actual: 38
        test/integration/microposts_interface_test.rb:25:in `block in <class:MicropostsInterfaceTest>'

  59/59: [======================================================================================================================================================================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.41207s
59 tests, 256 assertions, 1 failures, 0 errors, 0 skips
```

設定ファイルを生成する。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ touch config/initializers/skip_image_resizing.rb
```

テスト時はリサイズ処理をスキップする。

```/sample_app/config/initializers/skip_image_resizing.rb
if Rails.env.test?
  CarrierWave.configure do |config|
    config.enable_processing = false
  end
end
```

テストがgreenになることを確認。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ rails test
Running via Spring preloader in process 1833
Started with run options --seed 2677

DEPRECATION WARNING: ActionDispatch::IntegrationTest HTTP request methods will accept only==========                         ] 79% Time: 00:00:02,  ETA: 00:00:01
the following keyword arguments in future Rails versions:
params, headers, env, xhr, as

Examples:

get '/profile',
  params: { id: 1 },
  headers: { 'X-Extra-Header' => '123' },
  env: { 'action_dispatch.custom' => 'custom' },
  xhr: true,
  as: :json
 (called from block (2 levels) in <class:MicropostsInterfaceTest> at /home/ubuntu/workspace/sample_app/test/integration/microposts_interface_test.rb:27)
  59/59: [==================================================================================================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.69379s
59 tests, 262 assertions, 0 failures, 0 errors, 0 skips
```

##13.4.4 本番環境での画像アップロード
###本章での学び

####設定の切り替え
本番環境ではfog gemを使って、AWSのS3に画像をアップロードできるようにする。

```/sample_app/app/uploaders/picture_uploader.rb
  if Rails.env.production?
    storage :fog
  else
    storage :file
  end
```

####【事前準備】AWSのIAM設定
IAMユーザを追加する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/a037be76-9c88-d6a7-cfe4-b1213a66eeb8.png)

プログラムによるアクセスにチェックを入れる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/01f35479-5108-8502-fb33-393d2b2d5ab7.png)

ユーザーを作成して、AccessキーとSecretキーを取得する。

####【事前準備】S3バケットの作成
任意のバケットを作成する。
バケット名はユニークにする必要があるので注意。
リージョンは アジアパシフィック (東京)を選択する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/3bcb41de-ed37-14ff-00fe-689da132b2b2.png)

他の設定はデフォルトのまま。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/c6c5a2b5-1acc-c4fe-5afc-600c545a960b.png)

パブリックアクセスは付与しない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/e22e6fcb-8bf3-6304-2c93-ab2c7142e67e.png)

バケットの完成。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/cb525a8f-fa4a-e077-149c-19e8abdd36e1.png)

####【事前準備】CarrierWaveの設定ファイル作成
本番環境の場合に使用する、carrier_waveの設定ファイルを作成する。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ touch config/initializers/carrier_wave.rb
```

```/sample_app/config/initializers/carrier_wave.rb
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      # Amazon S3用の設定
      :provider              => 'AWS',
      :region                => ENV['S3_REGION'],
      :aws_access_key_id     => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY']
    }
    config.fog_directory = ENV['S3_BUCKET']
  end
end
```

####【事前準備】heroku側のAWS設定
Herokuの環境変数設定を行う。

```irb
$ heroku config:set S3_ACCESS_KEY="ココに先ほどメモしたAccessキーを入力"
$ heroku config:set S3_SECRET_KEY="同様に、Secretキーを入力"
$ heroku config:set S3_BUCKET="Bucketの名前を入力"
$ heroku config:set S3_REGION="Regionの名前を入力"
```

####【事前準備】gitignoreの編集
アップロードされたテスト画像が、gitで管理されないように、.gitignoreに追加する。

```/sample_app/.gitignore
# アップロードされたテスト画像を無視する
/public/uploads
```

####gitへのコミット、マージ
commit、mergeを行い、gitへpushする。

```irb
yokoyan:~/workspace/sample_app (user-microposts) $ rails test
yokoyan:~/workspace/sample_app (user-microposts) $ git add -A
yokoyan:~/workspace/sample_app (user-microposts) $ git commit -m "Add user microposts"
yokoyan:~/workspace/sample_app (user-microposts) $ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
yokoyan:~/workspace/sample_app (master) $ git merge user-microposts 
yokoyan:~/workspace/sample_app (master) $ git push
```

####本番環境へのリリース
Herokuへのデプロイを行う。

```irb
yokoyan:~/workspace/sample_app (master) $ git push heroku
```

データベースのリセットを行う。

```irb
yokoyan:~/workspace/sample_app (master) $ heroku pg:reset DATABASE
 ▸    heroku-cli: This CLI is deprecated. Please reinstall from https://cli.heroku.com
 ▸    WARNING: Destructive action
 ▸    postgresql-infinite-44520 will lose all of its data
 ▸    
 ▸    To proceed, type enigmatic-everglades-70434 or re-run this command with --confirm enigmatic-everglades-70434

> enigmatic-everglades-70434
Resetting postgresql-infinite-44520... done
```

データベースのマイグレーションを行う。

```irb
yokoyan:~/workspace/sample_app (master) $ heroku run rails db:migrate
 ▸    heroku-cli: This CLI is deprecated. Please reinstall from https://cli.heroku.com
Running rails db:migrate on ⬢ enigmatic-everglades-70434... up, run.7170 (Free)
D, [2017-08-23T04:06:30.854856 #4] DEBUG -- :    (37.2ms)  CREATE TABLE "schema_migrations" ("version" character varying PRIMARY KEY)
・・・略・・・
D, [2017-08-23T04:06:31.159450 #4] DEBUG -- :    (2.2ms)  COMMIT
D, [2017-08-23T04:06:31.161335 #4] DEBUG -- :    (1.7ms)  SELECT pg_advisory_unlock(414146247089748600)
```

本番環境のデータベースでサンプルデータを生成する。

```irb
yokoyan:~/workspace/sample_app (master) $ heroku run rails db:seed
・・・略・・・
D, [2017-08-23T04:08:49.010414 #4] DEBUG -- :    (0.9ms)  BEGIN
D, [2017-08-23T04:08:49.014906 #4] DEBUG -- :   SQL (1.1ms)  INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["content", "Recusandae asperiores dicta et consequatur praesentium error officia."], ["user_id", 6], ["created_at", 2017-08-23 04:08:49 UTC], ["updated_at", 2017-08-23 04:08:49 UTC]]
D, [2017-08-23T04:08:49.024077 #4] DEBUG -- :    (8.3ms)  COMMIT
```

###演習1
*本番環境で解像度の高い画像をアップロードし、適切にリサイズされているか確認してみましょう。長方形の画像であっても、適切にリサイズされていますか?*

本番環境にて解像度の高い画像をアップロードする。
本番環境では問題なくリサイズされていることを確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/60af4e21-6e91-c3ed-c5fe-cf34285bfc13.png)


#おわりに
画像の投稿ができるようになり、AWSのS3とも連携できるようになりました。
S3連携は敷居が高いかなと思っていたのですが、fog gemを入れれば簡単に連携することができました。
こういう豊富なgemが用意されているのもRailsの魅力ですね。

ローカルで発生した、translation missing: en.errors.messages.mini_magick_processing_errorエラーは未解決です。
gem側のバグなのか、環境依存の問題なのかの切り分けがまだできていませんが、
後日改めて調査したいと思います。