Railsの画像アップロードで必要に応じてCarrierWaveを回避したい

github.com

Ruby on Railsのフォームから画像をサーバにアップロードするというのを CarrierWave というGemを使って実装しています。

状況

ユーザー作成時に、基本的にはフォームからアバター用画像をアップロードさせるという簡単な実装で、もし画像の指定がなければそれを適用するというようなときにデフォルト画像を適用するということを実装しようとして少しハマったのでその回避方法を書いておきます。
Gemの中身を調べるということまで手が及んでいないので、回避方法が誤っているなどありましたら、指摘いただけると嬉しいです。

今回の僕の環境はRails 5.1です。

実装

実際には、S3へのデータアップロードなどをしていますが、今回は簡単のため、

  • name
  • image

f:id:zuckey_17:20180624233709p:plain:w200

を入力したら

  • Userのレコードが作成され
  • image にはファイル名が入り
  • 画像の実態はpublic/uploads に保存される

というような実装になっています。

# app/uploaders/user_image_uploader.rb

class UserImageUploader < CarrierWave::Uploader::Base
  storage :file
end

# app/models/users.rb

class User < ApplicationRecord
  mount_uploader :image, UserImageUploader
end

# app/controllers/user_controler.rb

  def create
    @user = User.new(user_params)
    
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

上記のように書くだけで先程の要件を満たすことができます。

回避方法

f:id:zuckey_17:20180624234531p:plain

さて、今回実現したいことは単純で、public/uploads/default.pngUser.imageに指定したいということです。

実際は以下の方法でCarrierWavemount_uploader 回避しました。

# app/controllers/user_controler.rb

  def create
    @user = User.new(user_params)

    # imageに指定がないとき、デフォルト画像を使う
    @user[:image] = "default.png" if params[:image].nil?
    @user.save
    
    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

@user.imageに代入することはできず、ブラケットでの指定しか成功しませんでした。 もう少し中身を見て挙動を把握したいです。