Reputation: 103
In my application I have a user, whose table in the database contains a boolean column for admin status. I want an admin to be able to change the admin status of any other user. The relevant view is:
<% @users.each do |user| %>
<tr>
...
<% if current_user && (current_user.id == user.id || current_user.admin) %>
...
<% if current_user.admin %>
<td><%= link_to 'Make admin', user.id.to_s + '/make_admin', {:method => 'post', :action => 'make_admin'} %></td>
<% if user.admin %>
<td><%= link_to 'Revoke admin', user.id.to_s + '/revoke_admin', {:method => 'post', :action => 'revoke_admin'} %></td>
<% end %>
...
</tr>
<% end %>
I wasn't sure how else to do it so I cobbled together the URL by concatenating the user's ID and the specific query. My controller begins with the restrictions which seem to prevent unauthorized access to these methods:
class UsersController < ApplicationController
...
before_action :admin_logged_in, only: [:edit, :update, :destroy, :make_admin, :revoke_admin]
And finally, my routing file looks like this:
Rails.application.routes.draw do
...
post ':id/make_admin' => 'users#make_admin'
post ':id/revoke_admin' => 'users#revoke_admin'
It seems to work, but I was wondering if there was a better way to do it. I've read the routing guide on Rails but little of it makes sense to me right now. I've tried linking directly to the user with
<%= link_to 'Make admin', user, {:controller => 'users', :action => 'make_admin'} %>
But I would receive an error about no route being defined for [POST]/user_id or something along those lines. That feels like the better solution in this case; if it is, what should I do in the routes.rb file to address this?
Upvotes: 1
Views: 55
Reputation: 616
You can add a helper to your routes like this :
post ':id/make_admin' => 'users#make_admin', as: 'make_admin'
Now make_admin_path(user.id)
will link to that. You can view all helpers either by running rake routes
in your site's directory or going to localhost:3000/rails/info
As for the error you got, I can't say for certain without seeing the full error, but when you <%= link_to 'text', user %>
ruby interprets user
at the path, and tries to find a user_path
and the {:controller => 'users', :action => 'make_admin'}
is a hash of HTML attributes that get added.
Upvotes: 0
Reputation: 503
You can create your routes as follows:
resources :users do
member do
post 'make_admin', as: :make_admin
post 'revoke_admin', as: :revoke_admin
end
end
I hope this helps you out
Upvotes: 1