class Gifted::Decorator

Public Class Methods

new() click to toggle source
# File lib/gifted/decorator.rb, line 12
def initialize
  @@decorators = {}
end

Public Instance Methods

decorate(obj) click to toggle source
# File lib/gifted/decorator.rb, line 16
def decorate(obj)
  if obj.is_a?(Array)
    obj.each { |r| decorate r }
  elsif obj.is_a?(Hash)
    obj.each_value { |v| decorate v }
  elsif obj.is_a?(ActiveRecord::Relation)
    extend_with_relation_decorator obj
  else
    extend_with_decorated obj

    return obj unless (d = decorator_for(obj.class))

    # !! The original monkey patched code.
    # obj.extend d unless obj.is_a? d

    # The new hotness, which mixes in a single "parent" method called `gift`, that isolates all
    # decorated methods; avoiding confusion as to which methods are decorated and which are not.
    #
    # Example:
    #   object.gift.my_decorated_method
    #   object.my_non_decorated_method
    #
    # Instead of extending (decorating) the given object with the decorator module, this extends
    # it with Gifted::Gift, and sets the default decorator as the calculated decorator module
    # above. Gifted::Gift extends the object with one method; `gift`, which returns the
    # default decorator.
    obj.extend(::Gifted::Gift).default_decorator = d unless obj.is_a? ::Gifted::Gift
  end

  obj
end
decorate_association(owner, target) click to toggle source

Decorates AR model object's association only when the object was decorated. Returns the association instance.

# File lib/gifted/decorator.rb, line 50
def decorate_association(owner, target)
  owner.is_a?(Gifted::Decorated) ? decorate(target) : target
end

Private Instance Methods

decorator_for(model_class) click to toggle source

Returns a decorator module for the given class. Returns `nil` if no decorator module was found.

# File lib/gifted/decorator.rb, line 58
def decorator_for(model_class)
  return @@decorators[model_class] if @@decorators.key? model_class

  decorator_name = "#{model_class.name}Decorator"
  d = Object.const_get decorator_name, false
  unless Class === d
    d.send :include, Gifted::ViewHelpers
    @@decorators[model_class] = d
  else
    # Cache nil results
    @@decorators[model_class] = nil
  end
rescue NameError
  # This handles ActiveRecord STI models which don't have a decorator class - looking up it's
  # base class.

  if model_class.respond_to?(:base_class) && (model_class.base_class != model_class)
    @@decorators[model_class] = decorator_for model_class.base_class
  else
    # Cache nil results
    @@decorators[model_class] = nil
  end
end
extend_with_decorated(obj) click to toggle source
# File lib/gifted/decorator.rb, line 88
def extend_with_decorated(obj)
  return if !obj.is_a?(ActiveRecord::Base) || obj.is_a?(Gifted::Decorated)

  obj.extend Gifted::Decorated
end
extend_with_relation_decorator(obj) click to toggle source
# File lib/gifted/decorator.rb, line 82
def extend_with_relation_decorator(obj)
  return if obj.is_a? Gifted::RelationDecorator

  obj.extend Gifted::RelationDecorator
end