Class: Draper::Decorator

Inherits:
Object
  • Object
show all
Extended by:
Delegation
Includes:
ActiveModel::Serialization, ActiveModel::Serializers::JSON, ActiveModel::Serializers::Xml, Compatibility::GlobalID, ViewHelpers
Defined in:
lib/draper/decorator.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Delegation

delegate

Methods included from ViewHelpers

#helpers, #localize

Constructor Details

#initialize(object, options = {}) ⇒ Decorator

Wraps an object in a new instance of the decorator.

Decorators may be applied to other decorators. However, applying a decorator to an instance of itself will create a decorator with the same source as the original, rather than redecorating the other instance.

Parameters:

  • object (Object)

    object to decorate.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :context (Hash) — default: {}

    extra data to be stored in the decorator and used in user-defined methods.



31
32
33
34
35
36
# File 'lib/draper/decorator.rb', line 31

def initialize(object, options = {})
  options.assert_valid_keys(:context)
  @object = object
  @context = options.fetch(:context, {})
  handle_multiple_decoration(options) if object.instance_of?(self.class)
end

Instance Attribute Details

#contextHash

Returns extra data to be used in user-defined methods.

Returns:

  • (Hash)

    extra data to be used in user-defined methods.



18
19
20
# File 'lib/draper/decorator.rb', line 18

def context
  @context
end

#objectObject (readonly) Also known as: model

Returns the object being decorated.

Returns:

  • the object being decorated.



14
15
16
# File 'lib/draper/decorator.rb', line 14

def object
  @object
end

Class Method Details

.collection_decorator_classClass

Returns the class created by decorate_collection.

Returns:



226
227
228
229
230
231
# File 'lib/draper/decorator.rb', line 226

def self.collection_decorator_class
  name = collection_decorator_name
  name_constant = name && name.safe_constantize

  name_constant || Draper::CollectionDecorator
end

.decorate_collection(object, options = {}) ⇒ Object

Decorates a collection of objects. The class of the collection decorator is inferred from the decorator class if possible (e.g. ProductDecorator maps to ProductsDecorator), but otherwise defaults to CollectionDecorator.

Parameters:

  • object (Object)

    collection to decorate.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :with (Class, nil) — default: self

    the decorator class used to decorate each item. When nil, it is inferred from each item.

  • :context (Hash)

    extra data to be stored in the collection decorator.



139
140
141
142
# File 'lib/draper/decorator.rb', line 139

def self.decorate_collection(object, options = {})
  options.assert_valid_keys(:with, :context)
  collection_decorator_class.new(object, options.reverse_merge(with: self))
end

.decorates(object_class) ⇒ void

Note:

This is only necessary if you wish to proxy class methods to the source (including when using decorates_finders), and the source class cannot be inferred from the decorator class (e.g. ProductDecorator maps to Product).

This method returns an undefined value.

Sets the source class corresponding to the decorator class.

Parameters:

  • object_class (String, Symbol, Class)

    source class (or class name) that corresponds to this decorator.



59
60
61
62
# File 'lib/draper/decorator.rb', line 59

def self.decorates(object_class)
  @object_class = object_class.to_s.camelize.constantize
  alias_object_to_object_class_name
end

.decorates_association(association, options = {}) ⇒ void

This method returns an undefined value.

Automatically decorate an association.

Parameters:

  • association (Symbol)

    name of the association to decorate (e.g. :products).

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :with (Class)

    the decorator to apply to the association.

  • :scope (Symbol)

    a scope to apply when fetching the association.

  • :context (Hash, #call)

    extra data to be stored in the associated decorator. If omitted, the associated decorator's context will be the same as the parent decorator's. If a Proc is given, it will be called with the parent's context and should return a new context hash for the association.



105
106
107
108
109
110
111
# File 'lib/draper/decorator.rb', line 105

def self.decorates_association(association, options = {})
  options.assert_valid_keys(:with, :scope, :context)
  define_method(association) do
    decorated_associations[association] ||= Draper::DecoratedAssociation.new(self, association, options)
    decorated_associations[association].call
  end
end

.decorates_associations(*associations, options = {}) ⇒ void

This method returns an undefined value.

Automatically decorate multiple associations.

Parameters:

  • associations (Symbols*)

    names of the associations to decorate.

  • options (Hash) (defaults to: {})


120
121
122
123
124
125
# File 'lib/draper/decorator.rb', line 120

def self.decorates_associations(*associations)
  options = associations.extract_options!
  associations.each do |association|
    decorates_association(association, options)
  end
end

.decorates_findersvoid

This method returns an undefined value.

Automatically decorates ActiveRecord finder methods, so that you can use ProductDecorator.find(id) instead of ProductDecorator.decorate(Product.find(id)).

Finder methods are applied to the object_class.



87
88
89
# File 'lib/draper/decorator.rb', line 87

def self.decorates_finders
  extend Draper::Finders
end

.delegate_allvoid

This method returns an undefined value.

Automatically delegates instance methods to the source object. Class methods will be delegated to the object_class, if it is set.



46
47
48
# File 'lib/draper/decorator.rb', line 46

def self.delegate_all
  include Draper::AutomaticDelegation
end

.object_classClass

Returns the source class corresponding to the decorator class, as set by decorates, or as inferred from the decorator class name (e.g. ProductDecorator maps to Product).

Returns:

  • (Class)

    the source class that corresponds to this decorator.



69
70
71
# File 'lib/draper/decorator.rb', line 69

def self.object_class
  @object_class ||= inferred_object_class
end

.object_class?Boolean

Checks whether this decorator class has a corresponding object_class.

Returns:

  • (Boolean)


74
75
76
77
78
# File 'lib/draper/decorator.rb', line 74

def self.object_class?
  object_class
rescue Draper::UninferrableObjectError
  false
end

Instance Method Details

#==(other) ⇒ Boolean

Compares the source object with a possibly-decorated object.

Returns:

  • (Boolean)


168
169
170
# File 'lib/draper/decorator.rb', line 168

def ==(other)
  Draper::Decoratable::Equality.test(object, other)
end

#applied_decoratorsArray<Class>

Returns the list of decorators that have been applied to the object.

Returns:

  • (Array<Class>)

    the list of decorators that have been applied to the object.



146
147
148
149
# File 'lib/draper/decorator.rb', line 146

def applied_decorators
  chain = object.respond_to?(:applied_decorators) ? object.applied_decorators : []
  chain << self.class
end

#attributesHash

implemented by the decorator.

Returns:

  • (Hash)

    the object's attributes, sliced to only include those



215
216
217
# File 'lib/draper/decorator.rb', line 215

def attributes
  object.attributes.select {|attribute, _| respond_to?(attribute) }
end

#decorated?true

Checks if this object is decorated.

Returns:

  • (true)


161
162
163
# File 'lib/draper/decorator.rb', line 161

def decorated?
  true
end

#decorated_with?(decorator_class) ⇒ Boolean

Checks if a given decorator has been applied to the object.

Parameters:

  • decorator_class (Class)

Returns:

  • (Boolean)


154
155
156
# File 'lib/draper/decorator.rb', line 154

def decorated_with?(decorator_class)
  applied_decorators.include?(decorator_class)
end

#eql?(other) ⇒ Boolean

Delegates equality to :== as expected

Returns:

  • (Boolean)


175
176
177
# File 'lib/draper/decorator.rb', line 175

def eql?(other)
  self == other
end

#hashFixnum

Returns a unique hash for a decorated object based on the decorator class and the object being decorated.

Returns:

  • (Fixnum)


183
184
185
# File 'lib/draper/decorator.rb', line 183

def hash
  self.class.hash ^ object.hash
end

#instance_of?(klass) ⇒ Boolean

Checks if self.instance_of?(klass) or object.instance_of?(klass)

Parameters:

  • klass (Class)

Returns:

  • (Boolean)


198
199
200
# File 'lib/draper/decorator.rb', line 198

def instance_of?(klass)
  super || object.instance_of?(klass)
end

#kind_of?(klass) ⇒ Boolean Also known as: is_a?

Checks if self.kind_of?(klass) or object.kind_of?(klass)

Parameters:

  • klass (Class)

Returns:

  • (Boolean)


190
191
192
# File 'lib/draper/decorator.rb', line 190

def kind_of?(klass)
  super || object.kind_of?(klass)
end