Two Models of Composing Actions

Subscribe to Two Models of Composing Actions 2 posts, 2 voices

 
Avatar Scott 7 posts

I’ve been working with authentication systems lately and I’m basically seeing actions composed in two different ways.

Model A

In Model A, a form posts back to the action that rendered it, and if the form post is successful then the action redirects elsewhere. For example, account creation in Acts As Authenticated is like this:

  • View Action: account/signup
  • View: views/account/signup.rhtml
  • HTML Form Action: account/signup

With this Psuedo Controller Code

def signup
  if not form post 
    render template
  else
    create new user
    if success
      redirect somewhere
    else
      re-render template with error message
    end
  end
end

As you can see, this action is very similar to what a Controller#new/Controller#create pair typically do, however the overall composition is using more of a “post back” technique.

Additionally, other methods in AAA (login, change_password, etc.) follow this model as well.

Model B

In Model B, the flow of things is more RESTful.

  • View Action: users/new
  • View: views/users/new.rhtml
  • HTML Form Action: users/create

With this Psuedo Controller Code:

def create
  create new user
  if success
    redirect somewhere
  else
    re-render action with error message
  end
end

As you see, is the more traditional Controller#new/Controller#create pair model. In my view, this is the evolving best practice because it’s more RESTful.

All that said, a few questions as I’m trying to get my head around authentication, but the thoughts are broadly applicable:

  • In authentication systems such as AAA, there is both an Account and User controller. But, there is no account model—both the User Controller and Account Controller act upon the User Model. This is what I am trying to get my head around: what is the philosophy or theory behind having two Controllers? Further, the actions in the Account Controller are typically formulated using Model A whereas in the User Controller the actions are formulated using Model B. Again, why?
  • Where do actions like login, logout, forgot_password, change_password belong. Those would seemingly be actions that “act on” a User, but they’re not RESTful (i.e. C, R, U or D). Perhaps this is why there is an Account Controller—it contains User actions that are not RESTful.
  • If that is true, then why does Account#signup exist? It seems to be a duplicate of the User#new/User#create pair (i.e. the C in CRUD). (In fact, this is what got me thinking about this whole topic: why does AAA implement both Account#signup and User#new/User#create?)

Bottom line: I’m trying to get my head around the role of the Account Controller, and the relationship between the Account Controller and User Controller. Underlying that question is a) I can’t make up my mind if I should have both Account and User, or just User, b) if I have both, then which actions belong in each, and c) which composition model from above is the appropriate best practice.

I hope I’ve expressed all that clearly…thoughts??

Scott

http://progress-vs-perfection.blogspot.com

 
Avatar Brian Eng 49 posts

It should be mentioned that restful_authentication is now somewhat preferred by most in the REST camp vs. AAA… looking at the code there may help clear up some confusion.

On to your questions.

Models != Resources. Models map to database tables. Resources are the… well, resources that your application provides to the outside world via HTTP. If you think of it that way, then the answer to your second question becomes clear. Login and logout (and it is implemented this way in restful_authentication) are simply the create and destroy methods on a “sessions” resource. Note that there is no session model, only a resource. Which is a perfect illustration of how resources do not necessarily have to map one-to-one to something in your database. As for stuff like change_password and forgot_password, it’s up to you whether you’d like to implement those RESTfully or decide that they’re just “oddball” actions that you want to stick on the end of some other controller. Example, you could do something like a ForgottenPasswordController and implement a new/create on that controller, or simply tack it onto the UsersController and be done with it.

Hope this helps.