简体   繁体   中英

Design Question (Ruby On Rails)

In my system there are many types of users (4), based on the user that is logged in they have access to only certain information.

For example I am trying to do something like this in my Client model:

 class Client
     def self.allowed
        if current_user.is_a?(SuperAdmin)
          return self.all
        elsif current_user.is_a?(Client)
          return [current_user]
        elsif current_user.is_a?(ClientAdmin)
          return [current_user.client]
        end
      end
   end

The problem is, it seems my model doesn't have access to the current_user helper method. (undefined local variable or method `current_user' for #)

I have 2 questions:

  1. How can I fix this
  2. Should logic such as getting back the allowed client be done in the model?

Using your methodology, I would define the method to allow passing in a user to check, as follows:

class Client
   def self.allowed(user)
      if user.is_a?(SuperAdmin)
        return self.all
      elsif user.is_a?(Client)
        return [user]
      elsif user.is_a?(ClientAdmin)
        return [user.client]
      end
    end
 end

Then, your controllers can decide which user should be checked based on the action being performed (although this will usually be current_user , this will free up your implementation to work with any user, so if you decide to add functionaly that depends on that fact later you're covered).

That being said, you should take at an authorization library; I personally really like CanCan . It allows you to define authorizations in one place, using a style similar to the one you present here. The author, Ryan Bates, has a great screencast on using CanCan .

1. How can I fix this

I can't tell without seeing how you're attempting to access the method, but you might consider the following in your ApplicationController :

before_filter :set_current_user

def set_current_user
  Client.current_user = current_user
end

This provides a copy of the current_user in your Client model.

2. Should logic such as getting back the allowed client be done in the model?

Most authentication systems I've used have placed the current_user (or equivalent function) in the ApplicationController , and provided methods to protect specific controller actions from access by unauthorized users. After all it's the controllers that should decide which users are able to access their actions, not the models.

Generally speaking, if you're trying to access members/methods of your controller from within your model, you're doing it wrong - that's not how information is supposed to flow through an MVC app.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM