Rails 画像投稿機能作成

##概要
※自分用メモです。
carrierwave,miimagickを使って画像投稿機能を作成手順について説明します。

使用イメージ

```dockerfile:Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    node.js \
    yarn \
    vim 

```

【参考】
以下の記事を参考にしました。

Rails 画像アップロード機能の実装方法　メモ
　　https://qiita.com/STHEXA/items/05a492bd9cf4cf31ba98

【Rails】CarrierwaveとMiniMagickを使って画像を投稿する方法
　　https://techtechmedia.com/carrierwave-minimagick-image/


##Gemの紹介
###・Carrierwave

画像をアップロードするためのgem

###・Minimagick

画像を加工してくれるgem

※MiniMagickを使うにはImageMagickというものをインストールする必要があるので注意しましょう。

ImageMagickは、画像処理ライブラリです。

・画像サイズ変更
・画像反転
・画像回転
・画像フォーマット変換
・色調整
・グラデーション

といった様々な画像処理を行うことができます。


##1.Dockerfile編集

参考にした記事によるとCarrierwaveの導入には「ImageMagick」がインストールされている必要があるみたいでしたので
DockerfileにImageMagickをインストールする記述を追記します。

```dockerfile:Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    node.js \
    yarn \
    vim \
    imagemagick     #←追記
```

##2.Gemfile編集

GemfileにCarrierwaveとMinimagickを追記します

```:gemfile
gem 'carrierwave'
gem 'mini_magick'
```


##3.docker-compose build 及び bundle installを実行

※dockerfileに`RUN bundle install`を記述してあれば`docker-compose build`を行えば
gemもインストールすることができます。

```
$ docker-compose build 
```

##4.アップローダーの作成
carrierwaveを利用するためのアップローダーを作成します。
※carrierwaveを導入したことで以下のコマンドが使えるようになります。

```
$ docker-compose exec web rails g uploader image 
```

もしくは

```
$ docker-compose exec web bash
$ rails g uploader image
```

上記のどちらかのコマンドで作成できます。

```:出力結果

# rails g uploader image
      create  app/uploaders/image_uploader.rb

```

##5.画像アップロードのフォームを作成(モデル,ビュー,コントローラー)

###・モデル編集

```rb:app/models/post.rb

class Post < ApplicationRecord
	mount_uploader :image, ImageUploader
end

```

###・コントローラー編集

```rb:app/controllers/posts_controller.rb

  def create
    @post = Post.new(post_params)
  end

  private

  def post_params
    params.require(:post).permit(:image)
  end

```


###・ビュー編集

```rb:app/views/posts/new.html.erb

<%= form_with model: @post, local: true do |f| %>

	<div class="form-group">
		<%= f.label :image, '画像' %>
		<%= f.file_field :image, accept: 'image/jpeg,image/gif,image/png' %>
	</div>
<%end%>

```


![スクリーンショット 2020-08-11 14.16.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451281/e16d5860-e0c8-e012-860a-6c9f9c5a0868.png)


※ここで以下のようなエラーが出ました。
uninitialized constant Post::ImageUploader

コンテナを一旦落として再度コンテナを立ち上げ直すと解消されました。

いろいろ調べていると再起動すればうまくいく？
とのことが書かれていたので試してみたところうまくいきました。

##6.アップロードされたときのサイズを設定
標準でアップロードされると大きいサイズの画像がアップロードされるのでサイズを変えるように設定します。

app/uploaders/image_uploader.rbに設定していきます。

```rb:app/uploaders/image_uploader.rb

class ImageUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  # ↓コメントアウト外す。
  include CarrierWave::MiniMagick

  # アップロードできるファイルの種類を制限
  def extension_whitelist
    %w(jpg jpeg gif png)
  end

  # アップロードするサイズの制限
  process resize_to_fit: [700, 700]

  # サムネイルサイズの設定
  version :thumb do
    process resize_to_fill: [100, 100]
  end

```


##補足
アップロードされた画像はどこへ保存されるの？

app/uploaders/image_uploader.rbに記述されています。

```rb:app/uploaders/image_uploader.rb

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

```

これはuploadeの中に保存されるという意味です

publicの中にuploadeのフォルダが作成されて保存されます。