Cherenkov
Cherenkov

Reputation: 495

Allow admin to activate or deactivate users-- Rails

I've managed to make an app that works only to sign up and to log in. Currently, I'm allowing users by mail account activation (following this tutorial: https://www.railstutorial.org/book/account_activation_password_reset and by 'rails generate controller AccountActivations --no-test-framework') but I want admin to be able to activate or deactivate users. In my users model, I managed to define two methods:

def activate_account!   
  update_attribute :is_active, true 
end

def deactivate_account!   
  update_attribute :is_active, false 
end

And on my users partial view, I managed to

<% if current_user.admin? && !current_user?(user) %> 
  <%= button_to "Deactivate", user, data: { confirm: "Are you sure?" } %> 
<% end %>

My routes look like this:

get 'password_resets/new'
get 'password_resets/edit'
root             'static_pages#home'
get 'help'    = 'static_pages#help'
get 'about'   = 'static_pages#about'
get 'contact' = 'static_pages#contact'
get 'signup'  = 'users#new'
get    'login'   = 'sessions#new'
post   'login'   = 'sessions#create'
delete 'logout'  = 'sessions#destroy'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets,     only: [:new, :create, :edit, :update]

The problem is that I don't know how to proceed. I don't want to use either Devise or CanCan because, as a beginner, I want to know how to do it manually. Please help me in implementing activation and deactivation of users from application (Admin can only this).

Here is my app.

Upvotes: 6

Views: 2805

Answers (2)

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34338

According to Rails convention:

PUT is used for updating an existing resource

POST is used for creating a new resource

So, you should make this a PUT request rather than POST as it is updating the user record.

You should define your route like this:

put 'deactivate/:id(.:format)', :to => 'users#deactivate', :as => :deactivate_user

And, in your user partial:

<%=link_to "Deactivate", deactivate_user_path(user), method: :put, data: { confirm: "You sure?" }%>

Everything should work now with your existing code.

Upvotes: 2

Chase
Chase

Reputation: 2826

Ok, first read chapters 9 and 10 of Hartl's Rails Tutorial.

Add and admin flag to users

rails g migration add_admin_to_users admin:boolean

This will give you .admin? "for free" as Active Record will generate this method.

And I'd write your button like this

<% if current_user.admin? && @user != current_user %> <%=link_to "deactivate", deactivate_path(user_id: @user), method: :post, data: { confirm: "Are you sure?" } %> <% end %>

Then in your controller:

def deactivate
  user = User.find(params[:user_id])
  if current_user.admin?
    user.deactivate_account!
    redirect_to users_path 
  else
    redirect_to :back
  end
end

And in your routes, something like:

post "/deactivate", to: "users#deactivate"

Anyway, I'm giving you a rough guide, but do read Hartl's tutorial, as your use case is almost covered there.

Good luck!

Upvotes: 6

Related Questions