hello-world
webエンジニアのメモ。とりあえずやってみる。

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

公開日時

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 '[email protected]' 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をブラウザで開いてみると、画像がアップロードされていることを確認できます。

参考


Related #carrierwave

[rails]carrierwaveで保存した画像のurlを取得する

carrierwave 0.10.0 で確認 imageカラムにcarrierwaveで保存した画像を保存している場合、デフォルトのままだとだとurlメソッドを実行してもpublic以下のパスのみで http://~ が設定されていません。

[rails]base64エンコードされた画像をcarrierwaveに保存する

Ruby 2.1.4, Rails 4.1.7 で確認 前回はcarrierwaveを使ってPOSTされた画像ファイルの保存を行うAPIを作ってみました。

[Rails]carrierwaveのcallbackをskip

Railsで画像アップロード機能を作る際に欠かせないgemと言えば carrierwave ですが、save時にcarrierwaveのcallbackをskipしたい場合の対応方法をメモしておきます。