jcasimir/draper — pull request #100 by angelim (2011-12-17 04:25:09+00:00)
Title: Multi decorator support

Sometimes we need multiple decorator representations for a given model. Suppose we have a class `Product` and multiple API versions are needed. For instance, the json output for an record's updated_at could use different formatting among API versions.

The current implementation of `Drapper::ModelSupport` infers the decorator class through the target name. Currently there's no convenient way for one to namespace a decorator or use an unconventional name that targets a conventional class and still be able to use de `ModelSupport#decorator` accessor.

Let me illustrate the first scenario:

```
class Product;end

class Api::ProductDecorator < Draper::Base
decorates :product
end

Product.new.decorate #=> NameError: uninitialized constant ProductDecorator
```

This patch provides an option to `Draper::Base.decorates` to define a `:version` for a decorator. This is useful in the following use cases:
- Use namespaced decorators for root target models.
- Using a decorator name that differs from its target model.

== Usage

```
class Product;end

class ProductDecorator < Draper::Base
decorates :product
end

class StoreProductDecorator < Draper::Base
decorates :product, :version => :store
end

class Api::ProductDecorator < Draper::Base
decorates :product, :version => :api
end

Product.new.decorate.class #=> ProductDecorator
Product.new.decorate(:version=>:store).class #=> StoreProductDecorator
Product.new.decorate(:version=>:api).class #=> Api::ProductDecorator
ApplicationController.decorate(Product.new, :version => :api) #also works

```

When one tries to create an unconventional decorator name without a :version option, the gem raises an error to avoid common mistakes.