Draper adds an object-oriented layer of presentation logic to your Rails application. Without Draper, this functionality might have been tangled up in procedural helpers or could have added bulk to your models. With Draper decorators, you can wrap your models with presentation-related logic to organise and test this layer of your app more effectively.
What We Will Use
- Draper gem (https://github.com/drapergem/draper)
- Decorator Pattern
Decorator Pattern is a design pattern which allows a developer to add an extra functionality to an object or a collection of objects. It is possible as a decorator class wraps a decorated model and deals only with the presentational issues. Also, it allows moving methods which are not related to a model strictly to separated classes make them cleaner. One of the common applications uses it inside the views but can be treated as another layer of abstraction.
Draper works on a model - view line, but the idea of a decorator pattern is not limited by any model or view. It is possible to decorate any class as you like it.
The Forwardable module provides delegation of specified methods to a designated object using the def delegator and def_delegators methods from the documentation (http://ruby-doc.org/stdlib-2.3.0/libdoc/forwardable/rdoc/Forwardable.html)
IMO the syntax is not clear enough, but - in some situations - it has a huge potential and could be used instead of Draper, being a part of std-lib of ruby which is easily accessible.
Decorate an object as well as a collection of objects.
Draper's methods are not visible in a global scope.
Dividing methods into smaller files.
The complexity of an app increases because we add an extra gem (IMHO it is still worth its price as we receive a cleaner design of an app).
It requires working the activemodel-serialisers-XML which was removed from Rails 5.
As of today (09/05/2016), there are a lot of problems with Rails 5.0-pre.
- Lack of maintainer in the project, which may cause problems in the future, especially when new bugs are found.
How Draper Works
delegate_all or delegate
- delegate_all allows a developer to decorate an object by all methods defined inside the decorator, but it is not always a good approach. In some cases, we would be better off delegating the method with a name which allows a developer to increase a legible of code and there is less metaprogramming.
- delegate_all https://github.com/drapergem/draper#delegating-methods
Add draper gem to Gemfile
Add a decorator class to a given class
Use object in order to class an instance of a model which will be decorated using your methods.
Do not forget about decorating your class in a controller by invoking decorate method on an instance of a model. Also, you can do it inside a view, but it is not the best approach.
See the example below:
I have decorated items in a presenter, which allows me to do more with a data presentation in the future, but you can decorate an object in a controller.
I think draper gem is mature and allows a developer to write methods which add extra functionality to its data. Actually, one of the biggest problems of draper gem is that it doesn't work with Rails 5 and its team has got a problem with a lack of maintainer.
It is a powerful tool, especially when a developer uses it with the presenter pattern. These two things allow a developer to make thinner controllers and models as well as move the logic to presenting the data in a cleaner way.