You’ve come across it before: you have a User model and a second model for
which users must be authorized to perform certain tasks:

defshow@event=Event.find(params[:id])unless(logged_in?&&(@event.members.include?(current_user)||@event.organizer.include?(current_user))||current_user.admin?)flash[:failure]="You are not authorized to view this event."redirect_tohome_urlandreturnendend

In discussion, we decided there is too much logic in the controller. We want to
move the authorization into the correct place in our domain model. Butwhere?

unless current_user.authorized_for_event?(@event)`

That reads nicely in English as “Unless the current user is authorized for the
event” but logically, a User should not be responsible for its own
authorization.

For example, I have a ticket to a Red Sox game. When I
arrive on Yawkey Way, the ticket-taker will authorize me to enter the event. He
or she is the Controller in our MVC
pattern. The ticket-taker doesn’t need to know that I paid with a MasterCard on
September 20th or that my seat is in right field or any other details. All that
matters is: is this guy authorized?

defattend@game=RedSoxGame.find_by_idparams[:id]unless@game.authorized?(current_user)flash[:failure]="You have no ticket for this game.
Watch it over a pint of Sam Adams at the Cask n' Flagon."redirect_tohome_urlandreturnendendclassRedSoxGame<ActiveRecord::Basedefauthorized?(user)returnfalseifuser.nil?doors_open?&&not_rained_out?&&user.ticket?(self)&&user.not_drunk?endend

The authorized method is noteworthy for two reasons. First, it uses the
Composed
Method:

Divide your program into methods that perform one identifiable task. Keep all
of the operations in a method at the same level of abstraction. This will
naturally result in programs with many small methods, each a few lines long.

The authorized? method is very easy to read because it focuses on simply
authorizing the user for the game. It relies on a number of other methods whose
purpose is clear and are similarly of narrow focus.

The second thing to note is that authorized? actually calls methods on the
User model. It may seem contradictory to call User after saying that
authorization logic does not belongs there. However, it isn’t authorization
logic; it’s another level of abstraction.