-
Notifications
You must be signed in to change notification settings - Fork 526
Upgrading to 1.0
A lot has changed in Draper 1.0! Here's a quick guide to the changes that might affect your app. work in progress
The most obvious change is that a lot of things have been renamed.
-
Draper::Base
is nowDraper::Decorator
. -
Draper::DecoratedEnumerableProxy
is nowDraper::CollectionDecorator
. -
Draper::ModelSupport
is nowDraper::Decoratable
. It's automatically included inActiveRecord::Base
andMongoid::Document
, so if your models inherit from these you're good to go. If not, you can manually include this module, which adds adecorate
instance method to your models.
Decorator.decorate(my_object)
is now just a simple alias for Decorator.new(my_object)
. The :infer
option has been removed, so if you want to infer the decorator from the source object, just use my_object.decorate
.
This also means that it no longer creates CollectionDecorator
s when you pass it an enumerable. You can therefore use a decorator on an array or similar, and it will decorate the collection itself instead of the items of the collection.
When you want to decorate each item of a collection, you should use the aptly named decorate_collection
method instead. ProductDecorator.decorate(Product.all)
becomes ProductDecorator.decorate_collection(Product.all)
.
Automatic decoration of ActiveRecord finder methods is no longer included by default. If you want to do ProductDecorator.find(1)
instead of ProductDecorator.decorate(Product.find(1))
or Product.find(1).decorate
, you need to call decorates_finders
in your decorator definition.
class ProductDecorator < Draper::Decorator
decorates_finders
end
decorates
is now optional. If you follow the standard naming convention that ProductDecorator
decorates a Product
, you can omit decorates
. In fact, if you don't intend to delegate class methods from the decorator to the model, you can omit it even if you don't follow the convention!
Previously, if you omitted decorates
, the decorator would use the class of the first object it decorated:
ProductDecorator.some_class_method # NoMethodError
ProductDecorator.decorate(Widget.first)
ProductDecorator.some_class_method # calls Widget.some_class_method
Now, the decorator infers the source class from its own name:
ProductDecorator.some_class_method # calls Product.some_class_method
ProductDecorator.decorate(Widget.first)
ProductDecorator.some_class_method # still calls Product.some_class_method
To get the object being decorated, there are several options. You can use my_decorator.model
, my_decorator.source
, or my_decorator.to_source
. Because decorators can be used on objects that are not models, we now prefer to use source
, which also works on collection decorators to get the undecorated collection. If you prefer it, model
is still available.
Previously, the decorator automatically aliased source
to the name of the model (e.g. a ProductDecorator
would have a product
method). This is no longer the case, and you should use alias_method :product, :source
in your decorator if you want to restore this behaviour.
You can take advantage of the free RSpec matchers that come with the new decorated?
and decorated_with?
methods:
my_object.should be_decorated
# or
my_object.should be_decorated_with ProductDecorator