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</span> = <span class="co">User</span>.invited.with_token(params[<span class="sy">:id</span>]).first <span class="no">4</span> raise <span class="co">ActiveRecord</span>::<span class="co">RecordNotFound</span> <span class="r">unless</span> <span class="iv">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</span> = <span class="co">User</span>.invited.with_token(params[<span class="sy">:id</span>]).first <span class="no"> 6</span> raise <span class="co">ActiveRecord</span>::<span class="co">RecordNotFound</span> <span class="r">unless</span> <span class="iv">user
7
8 user</span>.activate!(<span class="iv">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</span> ||= <span class="r">begin</span> <span class="no"> 6</span> <span class="co">User</span>.invited.with_token(params[<span class="sy">:id</span>]).first.tap <span class="r">do</span> |user| <span class="no"> 7</span> raise <span class="co">ActiveRecord</span>::<span class="co">RecordNotFound</span> <span class="r">unless</span> user <span class="no"> 8</span> <span class="r">end</span> <span class="no"> 9</span> <span class="r">end</span> <span class="no"><strong>10</strong></span> <span class="r">end</span> <span class="no">11</span> <span class="no">12</span> mandatory_steps <span class="r">do</span> <span class="no">13</span> <span class="iv">user = User.invited.with_token(params[:id]).first
14 raise ActiveRecord::RecordNotFound unless user</span> <span class="no"><strong>15</strong></span> <span class="no">16</span> <span class="iv">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