#AWSへデプロイ後に、user.saveでユーザー情報が保存できない現象についての対処法
とあるプログラミング学習サイトを利用してRailsを学び、作成したアプリケーションをサーバーへデプロイしたところまでは良かったのですが、その後作成したユーザーのアイコンを変更できない現象に遭遇しました。手探りでの対処で苦戦しましたので、同じことを繰り返さないためにも投稿に残したいと思います。
##現象が発生した元のコード
def update
@user = User.find_by(id: params[:id])
@user.name = params[:name]
@user.user_id = params[:user_id]
@user.email = params[:email]
if params[:image]
@user.image_name = "#{@user.id}.jpg"
image = params[:image]
File.binwrite("public/user_images/#{@user.image_name}", image.read)
end
if params[:password] != nil
@user.password = params[:password]
end
if @user.save
flash[:notice] = "ユーザー情報を編集しました"
redirect_to("/users/#{@user.user_id}")
else
render("users/#{@user.user_id}/edit")
end
end
このコードでローカルではうまくいっていたのですが、サーバーへデプロイ後はユーザー画像のみ保存されて、MySQLのデータは更新されませんでした。
##試したこと
エラーが吐き出されていないか確認しましたが、log/production.logにはエラーらしきものはなく、mysql.logを確認しようとしましたがどこにあるのかわからず、できませんでした。
このためはじめはrails consoleで状況を確認しようとしましたが、RDSのデータベースには接続されていないのか、users = User.allでユーザー情報を取得しようとしても、users.count = 0の状態でした。
そこで直接MySQLへログインして、テーブルのデータをSQLで更新してみたところ、こちらはできましたので、MySQLを使用して更新する方法を取ることにしました。
##現象が改善した後のコード
def update
id = @current_user.id
updated = 0
update_name_sql = "update users set name = '#{params[:name]}' where id =#{id};"
updated = ActiveRecord::Base.connection.execute(update_name_sql)
update_email_sql = "update users set email = '#{params[:email]}' where id =#{id};"
updated = ActiveRecord::Base.connection.execute(update_email_sql)
if params[:image]
update_image_name_sql = "update users set image_name = '#{id}.jpg' where id =#{id};"
updated = ActiveRecord::Base.connection.execute(update_image_name_sql)
image = params[:image]
File.binwrite("public/user_images/#{id}.jpg", image.read)
end
if params[:password]
hashed_password = BCrypt::Password.create(params[:password])
update_password_sql = "update users set encrypted_password = '#{hashed_password}' where id =#{@current_user.id};"
ActiveRecord::Base.connection.execute(update_password_sql)
end
if updated =! nil
flash[:notice] = "ユーザー情報を編集しました"
redirect_to("/users/#{@user.id}")
else
flash[:notice] = "データベースへの保存に失敗しました"
render("users/edit")
end
end
SQLを直に作成して、ActiveRecord::Base.connection.execute(SQL)でMySQLのデータベースを直接更新する方法へ変えました。
(パスワードに関してもトラブルがありましたので、直接暗号化してから保存するコードに書き換えました)
##まとめ
プログラミング学習サイトの良いところは、手軽に言語の学習に手をつけられるところですね。しかし現実には実用レベルに達するためにいくつもの壁を越えなければいけないものなのだと実感しています。ローカルでは動いていたけれど、サーバー環境ではうまくいかないことが普通にあるのだとわかりました。これに懲りずにポートフォリオ作りに励もうと思います!