まずは完成イメージから。
こんな感じで、新規ユーザー登録画面でユーザーアイコン用の画像も設定出来る仕様を実装してみます。 ちなみに、画像の登録は面倒だし、取りあえす画像は設定しないといった場合にはデフォルトで画像が自動で設定される仕様になっています。
コントローラーで、createアクションの設定
app/controllers/users_controller.rb
def create
@user = User.new(user_params)
image = params[:user][:user_image] ← この行を追加
hash = SecureRandom.hex(10) ← この行を追加
@user.user_image = "#{@user.name}_#{hash}.jpg" if image ← この行を追加
if @user.save
write_image(@user.user_image, image) if image ← この行を追加
session[:user_id] = @user.id
flash[:notice] = "ユーザー登録が完了しました"
redirect_to user_path(@user.id)
else
@user.user_image = image if image ← この行を追加
render :new
end
end
まずは下記の一文でuser_imageカラムにファイル名を入れています。
hash = SecureRandom.hex(10)
@user.user_image = "#{@user.name}_#{hash}.jpg" if image
ファイル名を"ユーザー名_ランダムな文字列"としています。
これは、なぜかと言うと、ユーザーの新規作成処理なので@user.saveとするまではユーザーidがありません。 そこで、ユーザー名とランダムな文字列(他の画像のファイル名と被らないように)をつけることでユニークな名前としています。
※ それに伴いupdateでも同じようにユーザー名+ランダムな文字列としました。
そして下記によってupdateと同様、ファイルに画像を書き込みしています。
# write_imageメソッドが呼ばれます。
write_image(@user.user_image, image) if image
コントローラーで、updateアクションの設定
def update
redirect_to user_path(@user.id) and return if @user.guest?
@user.name = params[:name]
@user.email = params[:email]
image = params[:image] ← この行を追加
hash = SecureRandom.hex(10) ← この行を追加
@user.user_image = "#{@user.name}_#{hash}.jpg" if image ← この行を修正
if @user.save
write_image(@user.user_image, image) if image ← この行を修正
flash[:notice] = "ユーザー情報を編集しました"
redirect_to user_path(@user.id)
else
@user.user_image = image ← この行を追加
render :edit ← この行を修正
end
end
ちなみに、ストロングパラメーターでは画像のカラムは設定していません。
def user_params
params.require(:user).permit(:name, :email, :password)
end
ビューで画像投稿フォームの追加
app/views/users
# app/views/new.html.erb
<%= form_with model: @user, url: "/users/create", multipart: true do |f| %>
<%= f.label "ユーザー名" %>
<%= f.text_field :name %>
<%= f.label "画像" %> ← この行を追加
<%= f.file_field :user_image %> ← この行を追加
<%= f.label "メールアドレス" %>
<%= f.email_field :email %>
<%= f.label "パスワード" %>
<%= f.password_field :password %>
<%= f.submit "新規登録" %>
ではサーバーを立ち上げてみましょう。
ユーザーの画像を登録して新規作成することができれば成功です!