norbornyl
norbornyl

Reputation: 103

Should I be linking to controller actions like this?

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

Answers (2)

Clark
Clark

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

Adnan Devops
Adnan Devops

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

Related Questions