The more I think about it, the more I believe Commands and Presenters are intertwined. If you don’t know what a Presenter is, I suggest reading these articles:

I’m building a gem to abstract the Command pattern in your applications. It’s not Rails-specific, but does know about ActiveRecord. Anyway, as I was writing my sample application, I noticed some duplication:

app/controllers/invitations_controller.rb
1 class InvitationsController < ApplicationController
2   def show
3     @user = User.invited.with_token(params[:id]).first
4     raise ActiveRecord::RecordNotFound unless @user
5     render :action => :confirm
6   end
7 end

app/commands/confirm_invitation_request_command.rb
 1 class ConfirmInvitationRequestCommand
 2   Komando.make_command self
 3 
 4   mandatory_steps do
 5     @user = User.invited.with_token(params[:id]).first
 6     raise ActiveRecord::RecordNotFound unless @user
 7 
 8     @user.activate!(@attributes)
 9   end
10 end

Notice the first two lines of InvitationsController#show and ConfirmInvitationRequestCommand#mandatory_steps: identical. Then I thought, what if the Command was also a Presenter? Then, I could refactor appropriately:

app/commands/confirm_invitation_request_command.rb
 1 class ConfirmInvitationRequestCommand
 2   Komando.make_command self
 3 
 4   def user
 5     @user ||= begin
 6       User.invited.with_token(params[:id]).first.tap do |user|
 7         raise ActiveRecord::RecordNotFound unless user
 8       end
 9     end
10   end
11 
12   mandatory_steps do
13     @user = User.invited.with_token(params[:id]).first
14     raise ActiveRecord::RecordNotFound unless @user
15 
16     @user.activate!(@attributes)
17   end
18 end

app/controllers/invitations_controller.rb
1 class InvitationsController < ApplicationController
2   def show
3     @user = ConfirmInvitationRequestCommand.new(:token => params[:id]).user
4     render :action => :confirm
5   end
6 end

Notice how the business logic of finding a user by token is nicely tucked away.

Of course, while writing this post, I realized that finding a User by token should live in my model, not in the controller or the command, but still: bear with me.

The Presenter pattern makes some decisions for the view: how to get at the objects to be shown, how to arrange them, how to save them as a group. Turns out my Command does essentially the same thing. Maybe we can think of Presenter as a special-case of Command? Such that Presenter is a Command to view an object? That seems logical to me.

Search

Your Host

A picture of me

I am François Beausoleil, a Ruby on Rails and Scala developer. During the day, I work on Seevibes, a platform to measure social interactions related to TV shows. At night, I am interested many things. Read my biography.

Top Tags

Books I read and recommend

Links

Projects I work on

Projects I worked on