Ruby on RailsでCarrierWaveを使用して画像のアップロードAPIを作成

Ruby on Railsで、画像のアップロード・ダウンロードを行うAPIを作成してみます。
今回はCarrierWaveを使用します。

下記をかなり参考にさせていただきました。
[[rails]carrierwaveを使って画像を保存するAPIサンプル](http://blog.hello-world.jp.net/ruby/2289/)

# 準備
## ImageMagickをインストールする
XQuartzをインストール
http://www.xquartz.org/

ImageMagickをインストール
http://cactuslab.com/imagemagick/

Ubuntuにインストールするときは下記コマンドを使用
`$ sudo aptitude install imagemagick`
`$ sudo aptitude install libmagick++-dev`
`$ gem install rmagick`

## CarrierWaveとRMagickのインストール
1.Railsのアプリケーションを作成(imageUploaderという名前のアプリケーションを作成)
`rails new imageUploader`

2.Gemfileを編集する
インストールディレクトリのGemfileを編集する
`vi Gemfile`
Carrier Waveと、画像リサイズ用にRMagick、定数管理にConfigを最後部に追加します

```rb:Gemfile
# CarrierWave
gem 'carrierwave'
# RMagick
gem 'rmagick'
# Config
gem 'config'
```
3.インストール

`bundle install --path vendor/bundler` 

　→はまった
　　 ImageMagickをインストールしていても、下記エラーが発生・・・
> checking for outdated ImageMagick version (<= 6.4.9)... no

`brew install imagemagick`
でBrewでインストールを試すことで無事インストール完了

# 作成
1.Modelを作成する

`rails g model ImageFile`

2.Migrationファイルを修正する
(db/migrate/yyyyMMddHHmmss_create_image_files.rbのような名前のファイル)

```rb:yyyyMMddHHmmss_create_image.rb
class CreateImageFiles < ActiveRecord::Migration
  def change
    create_table :image_files do |t|
      t.string :title
      t.string :image
      t.string :name
      t.timestamps
    end
  end
end
```

3.Migrationを実行
 
`rake db:migrate`

4.Uploaderを作成する
`rails g uploader photo`

5.modelにuploaderを設定

```rb:app/models/image_file.rb
class ImageFile < ActiveRecord::Base
  mount_uploader :image, PhotoUploader

  validates :title, presence: true
  validates :image, presence: true
  validates :name, presence: true
end
```

6.Controllerを作成

`rails g controller ImageFile`

7.Controllerにアクションメソッドを追加

```rb:app/controllers/image_file_controller.rb
class ImageFileController < ApplicationController
  def upload
    raise ArgumentError, 'invalid params' if params[:image].blank? || params[:name].blank?

    imageFile = ImageFile.create(image: params[:image])

    imageFile.title = params[:title]
    imageFile.name = params[:name]

    imageFile.save!

    render json: {
        title: imageFile.title,
        name: imageFile.name,
        image: imageFile.image.url
    }
  end
end
```

8.URLの設定

configの初期設定を実施
`rails g config:install`

config/initializers/以下にcarrierwave.rbを作成する

```rb:config/initializers/carrierwave.rb
CarrierWave.configure do |config|
  config.asset_host = Settings.url
end
```
※定数ファイルは下記

```yaml:config/settings.yml
url: 'http://localhost:3000'
```

9.ApplicationControllerの設定を変更する
コメントにあるとおり、APIを使うときはnull_sessionを使用するため、application_controllerの設定を変更

```rb:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  # protect_from_forgery with: :exception
  protect_from_forgery with: :null_session
end
```

10.routingを設定する

設定は、Controller名/Action名

```rb:config/routes.rb
Rails.application.routes.draw do
  #Image Uploader
  post 'image_file/upload'
end
```

# 動作確認

1.railsを起動する

`rails s`

2.curlで画像アップロード

`curl -F 'image=@sample.jpg' -F 'title=test' -F 'name=username' http://localhost:3000/image_file/upload`