Ruby on Railsのフォームから画像をサーバにアップロードするというのを CarrierWave
というGemを使って実装しています。
状況
ユーザー作成時に、基本的にはフォームからアバター用画像をアップロードさせるという簡単な実装で、もし画像の指定がなければそれを適用するというようなときにデフォルト画像を適用するということを実装しようとして少しハマったのでその回避方法を書いておきます。
Gemの中身を調べるということまで手が及んでいないので、回避方法が誤っているなどありましたら、指摘いただけると嬉しいです。
今回の僕の環境はRails
5.1です。
実装
実際には、S3へのデータアップロードなどをしていますが、今回は簡単のため、
- name
- image
を入力したら
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
上記のように書くだけで先程の要件を満たすことができます。
回避方法
さて、今回実現したいことは単純で、public/uploads/default.png
をUser.image
に指定したいということです。
実際は以下の方法でCarrierWave
の mount_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
に代入することはできず、ブラケットでの指定しか成功しませんでした。
もう少し中身を見て挙動を把握したいです。