#事の発端
Deviseで作ったUserモデルのテーブルにカラムを更新しようとするとできなかったことが始まりです。
意外なところで詰まったなぁと思ったので健忘録としてまとめます。
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to user_path(@user.id)
else
render :show
end
end
僕は月の走行距離をマイページにて追加したかった為詳細ページにform_withを構えています。
<%= form_with(model: @user, local: true, class: "goal-form") do |f| %>
<%= f.text_field :distance, placeholder: "目標を記入する", class: "form__text" %>
<%= f.submit "設定する", class: "btn btn-primary" %>
<% end %>
送られてくる値も間違ってなかったのでなんでやねんと思っていたとこでした。
そこで以下のエラーを見つけました。
#そもそもUserテーブルの編集にはPasswordの入力が必要だということ。
知りませんでした。
これまでユーザーの編集を行うことがなかったんです。
そこでPasswordを入力せずにユーザーの編集を行う方法を見つけました。
カラムを更新するには新たなコントローラの作成やメソッドが必要なようです。
まずは、users/registrations_controller.rbを作成します。
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_account_update_params, only: [:update]
protected
def configure_account_update_params
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
end
end
次にルーティングを設定します。
devise_for :users, controllers: {
registrations: 'users/registrations'
}
Userモデルを編集。メソッドを追加します。
メソッドを追加
def update_without_current_password(params, *options)
params.delete(:current_password)
if params[:password].blank? && params[:password_confirmation].blank?
params.delete(:password)
params.delete(:password_confirmation)
end
result = update_attributes(params, *options)
clean_up_passwords
result
end
end
Userモデルで定義したメソッドを呼び出します。
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_account_update_params, only: [:update]
protected
追加
def update_resource(resource, params)
resource.update_without_password(params)
end
def configure_account_update_params
devise_parameter_sanitizer.permit(:account_update, keys: [:distance])
end
また、モデルにpasswordのバリデーションがかかっているとまだエラーになると思うので外しておきましょう。
with_options presence: true do
validates :nickname
validates :email
validates :password ←消す
end
できました。ほぼコピペです…
ここで初見だった方々が多かったのでまとめてみました。
・:account_update・・・Updateをするときに指定する引数。
・blank?・・・中身が空もしくは存在しないときにtrueを返す。
・update_attributes・・・一つのカラムのみを変更できる。しかし、バリデーションがスルーされる為、エラーの判定位が出ない。(これに苦しめられた)
キリがないのでここまで。
#完成
これから、jsで今日走った距離が引かれて減っていくような機能を導入したいなと思います。
お疲れ様でした。
#参考文献