I understand that we’re supposed to avoid putting logic in the controller. So what is the proper way to implement things like user access controls. Let’s suppose I have User, where each instance has a flag method admin? that determines whether the user can access information from other users.
Option 1: Put access controls in custom model
Model:
class User < ActiveRecord::Base
def self.get_list(accessor)
return [] unless accessor.admin?
self.all
end
end
Controller:
class UsersController < ApplicationController
def index
@users = User.get_list(current_user)
end
end
current_user would probably be defined somewhere in the application controller.
Option 2: Put access controls in the controller
Model:
class User < ActiveRecord::Base
end
Controller:
class UsersController < ApplicationController
def index
@users = current_user.admin? User.all : []
end
end
There are also some peripheral consequences such as where tests go and how they’re implemented.
My instinct is that the first of the two options is preferable, but I’ve only ever used option 2 in the past. Also, it seems like the generally accepted (as far as I can tell) practice of putting on action-wide access filters is done at the controller level as in:
class UsersController < ApplicationController
before_filter :verify_logged_in
end
Any logic controlling routing of your application belongs in your controller. As for your example, the first is preferable but really there’s not much in it.
It’s easy for opinionated frameworks make us almost obsessive about doing things in a perceived correct way. In your example such a tiny amount of logic would, in my opinion, be perfectly fine to leave in your controller. If you were to abstract it, give it a descriptive name that described better what the method is doing otherwise you’re simply making your code needlessly difficult to read.