Reputation: 29
I have Account
model with attribute role
. Roles wrote with enum role: [:user, :admin]
. I want that if left one account with role admin
he can't update his role to user
. I think need to write something like this: @account = Account.where(role: params[: role])...
and then I don't know.
account.rb
class Account < ApplicationRecord
enum role: [:user, :admin]
end
accounts_controller.rb
class AccountsController < ApplicationController
def index
@accounts = Account.all
end
def update
@account = Account.find(params[:id])
redirect_to accounts_path if account.update(role: params[:role])
end
end
schema.rb
create_table "accounts", force: :cascade do |t|
t.integer "role", default: 0
end
Upvotes: 1
Views: 1730
Reputation: 11186
I think what you want is a model callback before_update
that acts like a validation.
class Account < ApplicationRecord
enum role: [:user, :admin]
before_update :insure_admin, if: -> { role == :admin && role_changed? }
private
def insure_admin
errors.add(:role, "admin cannot switch to regular user")
end
end
This should prevent the account.update(role: params[:role])
from returning true but you'll probably want to handle the error in your controller, something like:
class AccountsController < ApplicationController
def index
@accounts = Account.all
end
def update
@account = Account.find(params[:id])
if account.update(role: params[:role])
redirect_to accounts_path
else
redirect_to :back, flash: account.errors.full_messages
end
end
end
You might also want to add front end form validation to not allow the form to change role if the account is already persisted.
Upvotes: 2