I followed this link to figure out how to have an admin approve a new user. I have an approved
attribute on my User
model that is a boolean.
2 problems - 1) when I'm logged in as admin and go to the edit user via the link_to "Edit", edit_user_path(user)
to change approved user - the url is for the correct user but then the update action tries to update the current admin user.
2) I would prefer to have the override of the needed current password so I've put a method in the Registrations
controller to do this below but get this error:
error: unknown attribute 'current_password' for User.
So it won't override the current_password
and it won't update the correct non-admin user - Where am I going wrong?
class Ability
include CanCan::Ability
def initialize(user)
current_user ||= User.new # guest user (not logged in)
if current_user.admin == true
can :manage, :all
else
can :manage, User, id: user.id
end
end
end
Routes
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'registrations' }
resources :users
end
Controller
class RegistrationsController < Devise::RegistrationsController
def update_resource(resource, params)
resource.update_without_password(params) if current_user.admin == true
end
end
I spent a lot of time trying to solve this and didn't find any definitive, end-to-end complete examples online so I'm putting everything below so any new users to RoR/Devise hopefully won't have same problems.
Assuming Devise
is on the User
model. Ensure your Cancancan is setup accordingly. Something similar to this:
models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
#
current_user ||= User.new # guest user (not logged in)
if current_user.admin
can :manage, :all
else
can :manage, User, id: user.id
end
end
end
Follow the steps in here
He mentions have an 'admin-accessible only' page. In case someone's not sure how to do this:
class UsersController < ApplicationController
before_action :admin?, only: :index
def index
if params[:approved] == false
@users = User.where(approved: false)
else
@users = User.all
end
end
private
def admin?
redirect_to '/login' unless current_user.admin == true
end
end
Replace this line (I use .erb not .haml as he does in the link) %td= link_to "Edit", edit_user_path(user)
with this: <%= User.approved %>
<td>
<% if !User.approved %>
<%= link_to "Approve User", user_path(:id => user.id, "user[approved]" => true), :method => :patch, class: "btn btn-success" %>
<% else %>
<%= link_to "Unapprove User", user_path(:id => user.id, "user[approved]" => false), :method => :patch, class: "btn btn-danger" %>
<% end %>
</td>
This essentially gives you a button that when clicked, will approve the user and visa-versa. The key here that tripped me up for days is that a) You have to ensure that your form (in this case, the link_to
hits the Users controller and NOT the RegistrationsController#update
method.
I know some online links gave instructions to create a Registrations
model and changing routes, overriding models, etc.
Honestly, my final solution didn't need any of that. Hope this helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.