Class: Draper::Decorator

Inherits:
Object
  • Object
show all
Extended by:
Delegation
Includes:
ActiveModel::Serialization, ActiveModel::Serializers::JSON, ActiveModel::Serializers::Xml, 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.



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

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.



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

def context
  @context
end

#objectObject (readonly) Also known as: model, source, to_source

Returns the object being decorated.

Returns:

  • the object being decorated.



11
12
13
# File 'lib/draper/decorator.rb', line 11

def object
  @object
end

Class Method Details

.collection_decorator_classClass

Returns the class created by decorate_collection.

Returns:



242
243
244
245
246
247
248
# File 'lib/draper/decorator.rb', line 242

def self.collection_decorator_class
  name = collection_decorator_name
  name.constantize
rescue NameError => error
  raise if name && !error.missing_name?(name)
  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.



143
144
145
146
# File 'lib/draper/decorator.rb', line 143

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.



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

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.



109
110
111
112
113
114
115
# File 'lib/draper/decorator.rb', line 109

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: {})


124
125
126
127
128
129
# File 'lib/draper/decorator.rb', line 124

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.



91
92
93
# File 'lib/draper/decorator.rb', line 91

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.



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

def self.delegate_all
  include Draper::AutomaticDelegation
end

.object_classClass Also known as: source_class

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.



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

def self.object_class
  @object_class ||= inferred_object_class
end

.object_class?Boolean Also known as: source_class?

Checks whether this decorator class has a corresponding object_class.

Returns:

  • (Boolean)


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

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

Instance Method Details

#==(other) ⇒ Boolean

Compares the source object with a possibly-decorated object.

Returns:

  • (Boolean)


172
173
174
# File 'lib/draper/decorator.rb', line 172

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.



150
151
152
153
# File 'lib/draper/decorator.rb', line 150

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



231
232
233
# File 'lib/draper/decorator.rb', line 231

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

#decorated?true

Checks if this object is decorated.

Returns:

  • (true)


165
166
167
# File 'lib/draper/decorator.rb', line 165

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)


158
159
160
# File 'lib/draper/decorator.rb', line 158

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

#eql?(other) ⇒ Boolean

Delegates equality to :== as expected

Returns:

  • (Boolean)


179
180
181
# File 'lib/draper/decorator.rb', line 179

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)


187
188
189
# File 'lib/draper/decorator.rb', line 187

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

#inspectObject



210
211
212
213
214
215
# File 'lib/draper/decorator.rb', line 210

def inspect
  ivars = instance_variables.map do |name|
    "#{name}=#{instance_variable_get(name).inspect}"
  end
  _to_s.insert(-2, " #{ivars.join(", ")}")
end

#instance_of?(klass) ⇒ Boolean

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

Parameters:

  • klass (Class)

Returns:

  • (Boolean)


202
203
204
# File 'lib/draper/decorator.rb', line 202

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)


194
195
196
# File 'lib/draper/decorator.rb', line 194

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