Question

I have a situation in a Rails app where I will be using a similar type of code many times so I figure I should try and DRY it out. I'm relatively new to Ruby & Rails and I'm willing to bet that there is some kind of solution that I can use already made-- so I'd appreciate that, however, I also would like help understanding how best to go about this.

I feel like the solution I have, even if possible, is bad-- but I don't actually know so I figure its best to ask for some help.

Here are two examples of the code I expect to repeat:

def index
  if current_user && current_user.admin?
    @users = User.all
  else
    redirect_to root_url, :notice => "Access Unauthorized"
  end   
end

and another example:

def new
  if current_user && current_user.admin?
    @podcast = ApPodcast.new
  else
    redirect_to root_url, :notice => "Access Unauthorized"
  end   
end

I am using this conditional to make sure only admin users can access certain pages. I expect to be using this type of verification a lot unless I can find a better solution.

However, the idea I had is to make a helper method in ApplicationController that takes the name of an instance variable, name of a class, and a method to be called on that class similar to the following:

def admin_auth(instVar, class_to_use, method_call)
  if current_user && current_user.admin?
    instVar = class_to_use.method_call
  else
    redirect_to root_url, :notice => "Access Unauthorized"
  end
end

Is this plausible, effective or even possible? Is there a significantly better way to go about this? I've tried the above code and essentially get errors telling me that "method_call" doesn't exist so I assume when I call:

admin_auth(@user, User, all)

that I am not doing it right at all.

Again, any solution to help me keep my code DRY as every tutorial I've ever read recommends will be greatly appreciated-- but better than that is the understanding of any better solution.

Thanks.

Was it helpful?

Solution

To call a method on a class dynamically, you need to use send

def admin_auth(instVar, class_to_use, method_call)
    if current_user && current_user.admin?
        return class_to_use.send(method_call)
    else
        redirect_to root_url, :notice => "Access Unauthorized"
    end
end

You need the pass in the Class name as a constant and the method name as a string or a symbol

> @user = admin_auth(User, :all)
> @user = admin_auth(User, 'all')

OTHER TIPS

I'd suggest that you take a look at cancan https://github.com/ryanb/cancan

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top