Ruby
Heroku
RubyOnRails
Cloudi

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

はじめに

Rails x herokuで投稿系のサービスを作っていて、エディタに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に以下を入れます

gem 'cloudinary'

bundle installでgemを追加します。

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

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

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

ckeditorにcloudinaryを組み込む

cloudinaryについての基本的なことは、公式ドキュメントを参照してください。

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

ckeditor_attachment_file_uploader.rbを編集

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

# 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を編集していきます。
こっちももはや全部載せる

# 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

[: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を組み込むことが出来ます