Ckeditorの画像アップロードをCloudinaryに変更する

## はじめに

Rails x herokuで投稿系のサービスを作っていて、エディタに[ckeditor](https://github.com/galetahub/ckeditor)を使いました。
herokuで運用するので、アップロードされる画像ファイルを外部ストレージを使用する必要があったのでrailsとckeditorにcloudinaryを導入する方法です。

> rails x ckeditorの導入方法については、この記事では取り上げません。
> rails x ckeditorでの画像のアップロードには、carrierwaveを使っています。

## herokuへcloudinaryのアドオンを追加

herokuは公式にcloudinaryをサポートしています。
herokuにcloudinaryのアドオンを追加する必要があります。
> アドオンを追加するには、heroku側でクレジットカードの登録を行なっている必要があります

```
// 無料のstarterを追加します
$ heroku addons:add cloudinary:starter
```

上記で出来なかった場合は、

```
$ heroku addons:add cloudinary:starter -a アプリケーション名
```


## gemを追加

`Gemfile`に以下を入れます

```ruby
gem 'cloudinary'
```

`bundle install`でgemを追加します。

## cloudinary.ymlをインストールする

cloudinary.ymlを公式サイトからダウンロードするのですが、cloudinaryにアカウント登録をしなければいけません。
[こちら](https://cloudinary.com/users/register/free)よりアカウント作成を行い、以下リンクよりダウンロードを行なってください。
[cloudinary.ymlのダウンロードリンク](https://cloudinary.com/console/cloudinary.yml)

ダウンロードを行なったら、`config`フォルダ直下に`cloudinary.yml`を配置しておきます。

## ckeditorにcloudinaryを組み込む

cloudinaryについての基本的なことは、[公式ドキュメント](https://devcenter.heroku.com/articles/cloudinary)を参照してください。

carrierwaveで生成した、uploaderを編集していきます。

#### ckeditor_attachment_file_uploader.rbを編集

`app/uploaders/ckeditor_attachment_file_uploader.rb`を編集していきます。
部分的だとわかりづらいので、もはや全部載せる

```ruby
# encoding: utf-8
require 'carrierwave'

class CkeditorAttachmentFileUploader < CarrierWave::Uploader::Base
  # 以下を追加
  include Cloudinary::CarrierWave
  include Ckeditor::Backend::CarrierWave

  # Include RMagick or ImageScience support:
  # include CarrierWave::RMagick
  # include CarrierWave::MiniMagick
  # include CarrierWave::ImageScience

  storage :file

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/ckeditor/attachments/#{model.id}"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url
  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process :scale => [200, 300]
  #
  # def scale(width, height)
  #   # do something
  # end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_white_list
    Ckeditor.attachment_file_types
  end
end
```

#### ckeditor_picture_uploader.rbを編集

`app/uploaders/ckeditor_picture_uploader.rb`を編集していきます。
こっちももはや全部載せる

```ruby
# encoding: utf-8
class CkeditorPictureUploader < CarrierWave::Uploader::Base
  include Ckeditor::Backend::CarrierWave
  include Cloudinary::CarrierWave
  # Include RMagick or ImageScience support:
  # include CarrierWave::RMagick
  include CarrierWave::MiniMagick
  # include CarrierWave::ImageScience

  # Choose what kind of storage to use for this uploader:
  # storage :file

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  # def store_dir
  #   "uploads/ckeditor/pictures/#{model.id}"
  # end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url
  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process scale: [200, 300]
  #
  # def scale(width, height)
  #   # do something
  # end

  [:extract_content_type, :extract_size, :extract_dimensions].each do |method|
    define_method :"#{method}_with_cloudinary" do
      send(:"#{method}_without_cloudinary") if self.file.is_a?(CarrierWave::SanitizedFile)
      {}
    end
    alias_method_chain method, :cloudinary
  end

  process :extract_dimensions

  # Create different versions of your uploaded files:
  version :thumb do
    process resize_to_fill: [118, 100]
  end

  version :content do
    process resize_to_limit: [800, 800]
  end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_white_list
    Ckeditor.image_file_types
  end
end
```

`include Cloudinary::CarrierWave`と

```ruby
[:extract_content_type, :extract_size, :extract_dimensions].each do |method|
  define_method :"#{method}_with_cloudinary" do
    send(:"#{method}_without_cloudinary") if self.file.is_a?(CarrierWave::SanitizedFile)
    {}
  end
  alias_method_chain method, :cloudinary
end
```

を追記し、`storage :file`をコメントアウト。



以上でrails x ckeditorにcloudinaryを組み込むことが出来ます