fat-code-refactoring-techniques icon indicating copy to clipboard operation
fat-code-refactoring-techniques copied to clipboard

Earlier Draft: Presenters

Open justin808 opened this issue 11 years ago • 2 comments

A Name for a PORO

  • Some Object for Complicated controller setup for a view
  • Terminology is controversial in the context of prior literature.
  • Trying to describe a object that sits between a controller method and a view.
  • Could have used "Facade"

But Facade???

  • Fascades just don't sound very positive to me!
  • http://www.merriam-webster.com/dictionary/facade
  1. the front of a building;
  2. a false, superficial, or artificial appearance or effect
  • OK, too negative!

"Presenter"

  • Object used to facilitate presentation of data in the view, typically constructed in the controller method or maybe in the view.
  • Smooth sounding.
  • Easy to spell.

Presenter Applicable Situation

  1. Controller is initializing multiple instance variables for the view.
  2. Controller has several private methods supporting the public method associated with the action.
  3. View has lots of inline Ruby code for calculating instance variables
  4. Logic is specific to one controller method and one view, or maybe a couple different response types for the same controller method.
  5. Numerous view helper methods interacting just for one action.
  6. If you find same code in multiple presenters for same model, then see if you can move to a decorator or concern. A module is another option for DRY'ing up duplication.

Presenter Solution

  1. Create directory app/presenters and add this code to application.rb
    config.autoload_paths += %W(
      #{config.root}/app/presenters
    )
  1. Create subdirectory app/presenters/users
  2. Create presenter: User::FollowPresenter
  3. Controller instantiates the User::FollowPresenter that is used by the view.
  4. Move ruby code from view and the controller into the presenter.
  5. Possibly include this snippet of code so that view instance methods are available:
  include Draper::ViewHelpers

Presenter Advantages

  1. Clearly bundles the code around the work the controller is doing and what the view needs.
  2. Simplifies code at the controller and view layers.
  3. Provides the possibility of unit testing the Presenter.
  4. Easy to group related methods and memoize instance variables, which can be highly beneficial if fragment caching is used, as compared to instantiating instance variables in the controller..
  5. Good place for the calculation of a complicated cache key rather than a view helper.

Presenter Disadvantages

There might be simpler techniques than creating another class and object, such as putting some logic in the Draper decorator or a view helper. A few lines of inline ruby code may work better than moving this code to a separate class.

Review on Reviewable

justin808 avatar Apr 05 '14 03:04 justin808

Facade is a well-established pattern. I think the word sounding negative is a weak argument (it's an analogy to (architectural facade](http://en.wikipedia.org/wiki/Facade)).

include Draper::ViewHelpers instead of this, it would be useful to find the Rails-specific module, or solution (without draper).

Your disadvantages could be better stated, like: Adding a Presenter is writing yet another object, which you might not need -- a simple view helper might suffice.

gylaz avatar Apr 08 '14 22:04 gylaz

@gylaz In terms of Draper::ViewHelpers, there's quite a bit there. I wish Rails offered this more cleanly. The alternative is to patch together different solutions for view helpers and url helpers. I'm trying to make this super easy, and this one include line is easy.

justin808 avatar Apr 13 '14 05:04 justin808