While administering users, I'd like the administrator to be able to confirm a user's account using a checkbox to trigger the user's devise user.confirm method.
I initially thought I'd be able to use attr_accessor to setup a variable called confirm_now to be used as a boolean on the user form, then in the controller update action (or by before/after action callback) evaluate the boolean and confirm the user accordingly.
I'm still not quite sure if I need methods in the model to set and read the attr_accessor variable, I'm still getting my head around that...or perhaps I'm over-complicating this and should call the user.confirm method when clicking save (is this bad practice? - I'm hesitant to add this field into the user_params).
Model:
class User < ApplicationRecord
attr_accessor :confirm_now
...
Controller:
class UsersController < ApplicationController
...
def update
if params[:user][:password].blank?
params[:user].delete(:password)
params[:user].delete(:password_confirmation)
end
if [email protected]? && @user.confirm_now
@user.confirm
end
...
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :account_active, :confirm_now)
end
Form snippet (this evaluates and works as expected):
<% if [email protected]? %>
<%= f.input :confirm_now, label: 'Confirm User', as: :boolean, checked_value: true, unchecked_value: false %>
<% end %>
Rails Log (the attr_accessor is set when checked on the form):
Processing by UsersController#update as HTML
Parameters: {"authenticity_token"=>"...", "user"=>{"first_name"=>"gg", "last_name"=>"gg", "email"=>"[email protected]", "account_active"=>"1", "confirm_now"=>"true", "password"=>"[FILTERED]"}, "commit"=>"Save", "id"=>"45"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."first_name" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."first_name" ASC LIMIT $2 [["id", 45], ["LIMIT", 1]]
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."first_name" ASC LIMIT $2 [["id", 45], ["LIMIT", 1]]
Redirected to http://localhost:3000/users
Completed 302 Found in 6ms (ActiveRecord: 0.6ms | Allocations: 2665)
Thanks in advance!
To simplify I would make it a button, and pass the confirmed_at
field directly.
Parameter whitelisting:
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :account_active, :confirmed_at)
end
Form:
<%=
if @user.confirmed?
link_to 'Unconfirm user',
user_path(@user, { user: { confirmed_at: nil } }),
method: :patch
else
link_to 'Confirm user',
user_path(@user, { user: { confirmed_at: Time.current } }),
method: :patch
end
%>
Please adjust the paths/method types according to your routes.