[rails]carrierwaveを使って画像を保存するAPIサンプル


[まとめ] 現在開催中のKindleセール情報はこちら

Ruby 2.1.4, Rails 4.1.7 で確認

画像アップロード機能を作成する際にcarrierwaveをよく使うのですが毎回調べているので基本的な設定部分のメモを残しておきます。

1. carrierwaveの初期設定

  • Gemfileに以下を追加
gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'
  • bundle install
bundle install --path vendor/bundler
  • 適当なmodel作成(今回はuserモデルを作ってみます)
./bin/rails g model user
  • migration作成
# db/migrate/20141120154624_create_users.rb
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :profile_image

      t.timestamps
    end
  end
end

name と profile_image のみを持ったUserテーブルを作成します。

  • migrate実行
./bin/rake db:migrate
  • carrierwaveのuploaderを作成
./bin/rails g uploader ProfileImage

app/uploaders以下にprofile_image_uploader.rbが追加されます。

今回、uploaderの設定はデフォルトのままで使用します。

uploaderの設定を変更すればs3にアップロードすることも可能です。

  • modelにuploaderを組み込み
# app/models/user.rb

class User < ActiveRecord::Base
  mount_uploader :profile_image, ProfileImageUploader

  validates :name, presence: true
  validates :profile_image, presence: true
end

2. コントローラ作成

Userコントローラにupdateアクションを作成して、nameと画像を登録するAPI機能を作ってみます。

  • api用にapplication_controllerのprotect設定をnull_sessionに変更
# 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: :null_session
end
  • user_controller作成
./bin/rails g controller user update
  • updateアクション実装
class UserController < ApplicationController
  def update
    raise ArgumentError, 'invalid params' if params[:name].blank? || params[:profile].blank?

    user = User.find_or_create_by(name: params[:name])
    user.profile_image = params[:profile]
    user.save!

    render json: {
      name: user.name,
      profile_url: user.profile_image.url
    }
  end
end

jsonで登録情報を返すようにしています。

  • carrierwaveの画像URL設定

user.profile_image.urlの結果が正しくURLを返すようにasset_host設定をします。

今回はlocalhostの3000ポートでアプリケーションを動かすとして以下の設定を書いておきます。

(url設定に関してはこちらを参照)

# config/initializers/carrierwave.rb

CarrierWave.configure do |config|
  config.asset_host = 'http://localhost:3000'
end
  • routing修正
# config/routes.rb

Rails.application.routes.draw do
  post 'user/update'
end

これでコントローラの準備ができました。

3. curlコマンドでAPIにアクセスしてみる

  • アプリケーション起動
./bin/rails s
  • curlで画像アップロード
curl -F 'name=test' -F 'profile=@sample.jpeg' http://localhost:3000/user/update

# {"name":"test","profile_url":"http://localhost:3000/uploads/user/profile_image/1/sample.jpeg"}

curlコマンドにFオプションとファイル名に@をつけて実行すれば画像をpostできます。

APIのレスポンスに書いてあるprofile_urlをブラウザで開いてみると、画像がアップロードされていることを確認できます。

参考

[まとめ] 現在開催中のKindleセール情報はこちら