Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RailsConf: Draper Decorators #10

Open
wants to merge 2 commits into
base: rc-concerns
Choose a base branch
from
Open

RailsConf: Draper Decorators #10

wants to merge 2 commits into from

Conversation

justin808
Copy link
Member

RailsConf 2014 Talk, Tuesday, 2:30, Ballroom 4, Concerns, Decorators, Presenters, Service Objects, Helpers, Help Me Decide!

Draper Decorator

Code: Github Fat Code Refactoring Techniques Pull Request Draper

Example: Added Draper Decorator class MicropostDecorator. Method posted_ago dries up code in 2 views.

Why?

  1. You're putting presentation code in your model or model-concerns.
  2. You want to organize some helper methods by models.
  3. You've got logic in your controllers/views that is strictly related to
    one model, but multiple controllers/views.
  4. You need a good place to consolidate the creation of flash messages related
    to a given model.

To quote the Draper Readme:

Decorators are the ideal place to:

  • format complex data for user display
  • define commonly-used representations of an object, like a name method that
    combines first_name and last_name attributes
  • mark up attributes with a little semantic HTML, like turning a url field
    into a hyperlink

What?

Steps

  1. Add gem 'draper'= and run =bundle
  2. Run Draper generator: rails generate decorator User, which creates
    app/decorators/user_decorator.rb and
    spec/decorators/user_decorator_spec.rb.
  3. Move presentation specific view code to decorator.
  4. Put h. in front of calls to helpers.
  5. Remove references to the model in the decorator, as the method is
    essentially on the model.
  6. Call model.decorate to get a decorated instance of the model.

Draper Applicable Situations

  1. Extension to model that only applies to views and presentation.
  2. Calculations done in view using model object.
  3. Code in view helper that is more closely aligned with the model.
  4. Code is that seems relatively general as opposed to clearly useful in
    only one view.
  5. If method feels relatively generic for views, but specific for a
    given model, then the decorator is a good place to put the method.

Draper Advantages

  1. Relatively simple way to add functionality to the model that only
    applies to the connection of the model to the view.
  2. Can separate presentation specific code from the model.
  3. Methods added to the model via the decorator have access to both view
    helper methods as well as the model.
  4. It's super easy to automatically convert the retrieved model object
    into it's decorated instance, either manually or automatically, at
    the controller layer.
  5. Simple to find the decorator methods, such as using for verification
    in feature specs.

Draper Disadvantages

  1. Shares similar problems with concerns in that the model object is
    still getting fatter.
  2. If there's multiple methods needed for some complex logic, that
    should be broken into it's own PORO.
  3. The advantage of ease of adding more methods can also be a
    disadvantage in that the Decorator can turn into a junk-drawer of
    loosely coupled methods.

Review on Reviewable

@justin808 justin808 changed the title RailsConf: decorators RailsConf: Decorators Apr 18, 2014
@justin808 justin808 changed the title RailsConf: Decorators RailsConf: Draper Decorators Apr 19, 2014
@justin808 justin808 mentioned this pull request Apr 19, 2014
Per Draper instructions for spork, added
  require 'draper/test/rspec_integration'
to spec_helper.rb
DRYs up code where printing how long ago a post was created.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant