Class: Tint::Decorator

Inherits:
Draper::Decorator
  • Object
show all
Includes:
JsonConversion
Defined in:
lib/tint.rb,
lib/tint/decorator.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from JsonConversion

#as_json

Constructor Details

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

Returns a new instance of Decorator.



13
14
15
16
17
# File 'lib/tint/decorator.rb', line 13

def initialize(object, options = {})
  super(object, options.except(:parent_decorator, :parent_association))
  @object_attributes = {}
  @context = @context.merge(options.slice(:parent_decorator, :parent_association))
end

Class Attribute Details

._attributesObject

Returns the value of attribute _attributes.



28
29
30
# File 'lib/tint/decorator.rb', line 28

def _attributes
  @_attributes
end

._override_methodsObject

Returns the value of attribute _override_methods.



28
29
30
# File 'lib/tint/decorator.rb', line 28

def _override_methods
  @_override_methods
end

.parent_associationObject

Returns the value of attribute parent_association.



28
29
30
# File 'lib/tint/decorator.rb', line 28

def parent_association
  @parent_association
end

.parent_decoratorObject

Returns the value of attribute parent_decorator.



28
29
30
# File 'lib/tint/decorator.rb', line 28

def parent_decorator
  @parent_decorator
end

Instance Attribute Details

#object_attributesObject

Returns the value of attribute object_attributes.



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

def object_attributes
  @object_attributes
end

Class Method Details

.already_eager_loaded_associations?(object) ⇒ Boolean

Returns:

  • (Boolean)


144
145
146
147
148
149
150
# File 'lib/tint/decorator.rb', line 144

def already_eager_loaded_associations?(object)
  if object.respond_to?(:association_cache)
    object.association_cache.any?
  else
    true
  end
end

.attributes(*options) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/tint/decorator.rb', line 38

def attributes(*options)
  @_attributes ||= Set.new

  return if options.blank?

  mapped_attrs = options.extract_options!

  link_mappings_to_object(mapped_attrs)

  delegated_attrs = options

  link_delegations_to_object(delegated_attrs)
end

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



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/tint/decorator.rb', line 98

def decorate(object, options = {})
  object_class = object.class

  _object_attributes =
      if object.present? && object.respond_to?(:attributes)
        object.attributes
      else
        {}
      end

  @object_attributes =
      if _object_attributes && _object_attributes.kind_of?(Hash)
        _object_attributes
      else
        {}
      end

  unless already_eager_loaded_associations?(object)
    object =
        if responds_to_methods?(object_class, :includes, :find) && eager_loads.present?
          object_class.includes(eager_loads).find(object.id)
        else
          object
        end
  end

  super(object, options)
end

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



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/tint/decorator.rb', line 83

def decorate_collection(collection, options = {})

  collection_with_eager_loads =
    if collection.respond_to?(:includes) &&
      eager_loads.present?  &&
       !parent_eager_loads_include_own?(options[:context])

      collection.includes(eager_loads)
    else
      collection
    end

  super(collection_with_eager_loads, options)
end

.decorates_association(*args) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/tint/decorator.rb', line 56

def decorates_association(*args)
  options = args.extract_options!
  association_chain = args

  association_tail = association_chain.last

  options[:with] ||= (association_tail.to_s.camelize.singularize + 'Decorator').constantize

  association_alias = options.delete(:as) || association_tail

  options.assert_valid_keys(:with, :scope, :context)

  define_association_method(association_alias, association_chain, options)

  eager_load_association(association_chain, options)
end

.decorates_associations(*arguments) ⇒ Object



73
74
75
76
77
78
79
80
81
# File 'lib/tint/decorator.rb', line 73

def decorates_associations(*arguments)

  options = arguments.extract_options!
  association_list = arguments

  association_list.each do |association_name|
    decorates_association(association_name, options.dup)
  end
end

.eager_load(*schema) ⇒ Object



52
53
54
# File 'lib/tint/decorator.rb', line 52

def eager_load(*schema)
  self.eager_loads = self.eager_loads.deeper_merge(expand_schema(schema))
end

.eager_loadsObject



30
31
32
# File 'lib/tint/decorator.rb', line 30

def eager_loads
  @_eager_loads ||= {}
end

.eager_loads=(value) ⇒ Object



34
35
36
# File 'lib/tint/decorator.rb', line 34

def eager_loads=(value)
  @_eager_loads = value
end

.ids_for(*options) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/tint/decorator.rb', line 160

def ids_for(*options)
  mapped_attrs = options.extract_options!

  attribute_options = options.map do |association_name|
    association_method = method_name_from_association(association_name)
    eager_load(association_name)
    association_method
  end

  attribute_options.push(
      mapped_attrs.inject({}) do |memo, key_and_value|
        association_name, value = key_and_value
        memo[value] = method_name_from_association(association_name)

        eager_load(association_name)
        memo
      end
  )

  attributes(*attribute_options)
end

.parent_eager_loads_include_own?(context = {}) ⇒ Boolean

Returns:

  • (Boolean)


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/tint/decorator.rb', line 127

def parent_eager_loads_include_own?(context = {})

  if context && context[:parent_decorator]
    if (parent_eager_loads = context[:parent_decorator].class.eager_loads)

      association_eager_load =
        context[:parent_association].inject(parent_eager_loads) do |memo, chain_link|
          memo[chain_link] if memo
        end

      !!association_eager_load
    end
  else
    false
  end
end

.responds_to_methods?(object, *methods) ⇒ Boolean

Returns:

  • (Boolean)


152
153
154
155
156
157
158
# File 'lib/tint/decorator.rb', line 152

def responds_to_methods?(object, *methods)
  methods.each do |method_name|
    return false unless object.respond_to?(method_name)
  end

  true
end

Instance Method Details

#column_namesObject



19
20
21
# File 'lib/tint/decorator.rb', line 19

def column_names
  object.class.column_names
end

#persisted?Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/tint/decorator.rb', line 23

def persisted?
  object.persisted?
end