Posts Tagged MVP

Rails Misapprehensions: What the fuck is MVP?

Thursday, November 11th, 2010

People usually make me feel slightly embarassed when they ask things like “How does Cells handle MVP?” or, even better, “Is there any MVP implementation in Cells?”.

Frankly, I don’t have a fucking clue about the real differences between MVP and MVC. In the past I usually deflected people’s attention by buying beers instead or whatever. I hope to find some answers in the comments section, soon.

After actually reading a bit about “MVP, Presenters and Rails” I came to the following conclusions:

  • There simply is no difference between MVP and MVC (imho)
  • Rails Presenters don’t implement the MVP/MVC pattern completely (imho)
  • And, if Rails would be real MVC we wouldn’t need Presenters. (imho)

As always, these theses are subject to discussion.

The confusion about MVC and Rails

So the first problem I already discussed in one of my recent posts is that Rails encourages a very monolithic controller architecture having one controller being responsible for a complete page.

As Rails is an opinionated framework, their MVC-definition is absolutely ok for me. However, this is not the MVC known from GUIs – usually you’d have multiple controller-view couples in your page UI, each pair implementing complex elements like forms, menus or pageable lists.

But we already talked about that, I just wanted to point out that this is the root of the mysterious MVP misapprehension in Rails.

MVP, where art thou?

Anybody being seriously interested in GUI design patterns read Martin Fowler’s paper describing MVC, MVP, Presentation model and friends.

To be honest, I still did not understand the difference. Luckily, Martin himself seemed to realize that it is tremendously difficult to discern between the two patterns, and split MVP into Supervising Controller and Passive View (some people alleged that I’m a fan of the latter, which I’m not!).

What I basically get from these excellent writings is that

“Presenters are a loose form of MVC controller. As a result a lot of designs will follow the MVP style but use ‘controller’ as a synonym for presenter.”

which I for myself cut down to MVP == MVC” – at least in a Rails-like web development environment.

It just simplifies things.

Presenters in Rails

In the past years a couple of Presenter implementations emerged and several clever writings about that pattern popped up. I was happy to read Dmytro Shteflyuk’s blog post about his presenter project, although I disagree in some points (I’m an asshole).

The word Presenter obviously refers to the P in MVP, and in Rails they roughly work like this.

class ShowPresenter
  def top_videos
    @top_videos ||= Video.top.all(:limit => 10)
  end

After defining the data aggregating code you can use the presenter in your rendering layer.

<% cache('home/top_videos') do %>
 <%= render 'videos', :videos => @presenter.top_videos %>
<% end %>

So, we retrieve data in the presenter and then pass it to the partial, right? This approach is of course a thousand times better than collecting data for presentation in the view itself.

Help me! What’s a Presenter?

However, in my understanding of the Supervising Controller pattern (which seems to supersede MVP), we need two crucial parts in order to be a Supervising Controller at all:

  • a view to display, well, data
  • a controller to handle input response and complex view logic

Please don’t get me wrong and correct me, I appreciate any approach different from Rails’ traditional VC-stack.

However, to me it seems that presenters in Rails only handle the “complex view logic part” (“collecting the videos to display”), whereas the monolithic ActionController still renders the view and handles input responses.

Am I wrong here? Is the ActionController itself the Supervising Controller which calls a presenter and then renders a view? I’m confused.

Cells is truly MVC, but is it different from Presenters?

After all this confusion and hyperlinking I’d like to stand up for my own solution for this dilemma. Let’s comment Dmytro’s (maybe outdated) blog post where he ponders the benefits of Presenter vs. Cells telling us to use presenters whenever you

  • have too much logic in views
  • get into trouble with already cached data within views
  • can’t test an action anymore because of its complexity

and to use Cells only when

  • you need a reuseable partial with initialization code

Well, I don’t agree here. Cells do all the stuff presenters do, and more. That doesn’t mean you should use Cells everywhere in place of partials and Presenters, but nevertheless comparing Cells and Presenters is discerningly.

Presenters are data aggregators, whereas Cells are autonomous MVC stacks as claimed by the true MVC pattern. This is a bit like comparing controllers with ActiveRecord’s finder.

Presenter gets Cell

Let’s see how the former example would look with a cell.

class ShowCell < Cell::Base
  def top_videos
    @top_videos ||= Video.top.all(:limit => 10)
 
    render
  end
  cache :top_videos
end

The cell would also contain a separate view in its namespace.

Note how simple the actual cell rendering in the controller is since we handle cell caching within the cell itself!

Here, my top porns:
<%= render_cell :show, :top_videos %>

Can you see the difference?

  • Cells can aggregate and prepare data just like presenters in their methods.
  • They keep their views separated, taking away complexity from the monolithic controller
  • Handling caching within a cell drastically reduces controller’s duties and is easier testable, too
  • Both data preparation and rendering is testable in a fine-grained cell scope
  • Cells can also inherit views from parent cells which wouldn’t work with a controller+presenter approach!

By no means do I discourage usage of presenters! Use it, as long as rendering the presented data in the controller scope is clear. If it gets too complex (or if you need any other advantages cells have), use Cells.

MVC, done right

One of my intentions was to show that you don’t need presenters if you have a true MVC framework with multiple controllers/views – you can simply wrap data retrieval, rendering and optimization code (like caching) in a separate controller.

That is how GUIs used to work for decades and how web based frameworks should evolve.