2011-10-20 05:43:48 +00:00
|
|
|
module Draper
|
2012-10-09 09:07:14 +00:00
|
|
|
class CollectionDecorator
|
2011-10-20 05:43:48 +00:00
|
|
|
include Enumerable
|
2013-01-14 03:27:58 +00:00
|
|
|
include Draper::ViewHelpers
|
2019-02-25 16:44:19 +00:00
|
|
|
include Draper::QueryMethods
|
2013-01-14 03:27:58 +00:00
|
|
|
extend Draper::Delegation
|
2011-10-20 05:43:48 +00:00
|
|
|
|
2014-06-20 19:13:05 +00:00
|
|
|
# @return the collection being decorated.
|
|
|
|
attr_reader :object
|
|
|
|
|
2013-02-15 08:03:08 +00:00
|
|
|
# @return [Class] the decorator class used to decorate each item, as set by
|
|
|
|
# {#initialize}.
|
|
|
|
attr_reader :decorator_class
|
|
|
|
|
2013-01-07 16:33:24 +00:00
|
|
|
# @return [Hash] extra data to be used in user-defined methods, and passed
|
|
|
|
# to each item's decorator.
|
2012-12-19 21:48:37 +00:00
|
|
|
attr_accessor :context
|
|
|
|
|
2017-05-05 15:53:30 +00:00
|
|
|
array_methods = Array.instance_methods - Object.instance_methods
|
2012-12-29 12:43:33 +00:00
|
|
|
delegate :==, :as_json, *array_methods, to: :decorated_collection
|
2012-08-29 21:13:23 +00:00
|
|
|
|
2013-04-30 13:10:52 +00:00
|
|
|
# @param [Enumerable] object
|
2013-01-07 16:33:24 +00:00
|
|
|
# collection to decorate.
|
|
|
|
# @option options [Class, nil] :with (nil)
|
2013-04-15 21:55:20 +00:00
|
|
|
# the decorator class used to decorate each item. When `nil`, each item's
|
2013-01-07 16:33:24 +00:00
|
|
|
# {Decoratable#decorate decorate} method will be used.
|
|
|
|
# @option options [Hash] :context ({})
|
|
|
|
# extra data to be stored in the collection decorator and used in
|
|
|
|
# user-defined methods, and passed to each item's decorator.
|
2013-04-30 13:10:52 +00:00
|
|
|
def initialize(object, options = {})
|
2013-03-10 07:47:53 +00:00
|
|
|
options.assert_valid_keys(:with, :context)
|
2013-04-30 13:10:52 +00:00
|
|
|
@object = object
|
2012-12-19 21:45:22 +00:00
|
|
|
@decorator_class = options[:with]
|
2012-12-13 06:38:15 +00:00
|
|
|
@context = options.fetch(:context, {})
|
2012-08-30 13:00:37 +00:00
|
|
|
end
|
2012-05-09 20:48:28 +00:00
|
|
|
|
2012-10-31 23:49:12 +00:00
|
|
|
class << self
|
2019-05-31 14:08:31 +00:00
|
|
|
alias :decorate :new
|
2011-10-20 05:43:48 +00:00
|
|
|
end
|
|
|
|
|
2013-01-07 16:33:24 +00:00
|
|
|
# @return [Array] the decorated items.
|
2012-05-09 20:48:28 +00:00
|
|
|
def decorated_collection
|
2013-04-30 13:10:52 +00:00
|
|
|
@decorated_collection ||= object.map{|item| decorate_item(item)}
|
2011-10-20 05:43:48 +00:00
|
|
|
end
|
|
|
|
|
2017-03-29 15:26:07 +00:00
|
|
|
delegate :find, to: :decorated_collection
|
2012-08-18 09:54:16 +00:00
|
|
|
|
2011-10-20 05:43:48 +00:00
|
|
|
def to_s
|
2013-04-30 13:10:52 +00:00
|
|
|
"#<#{self.class.name} of #{decorator_class || "inferred decorators"} for #{object.inspect}>"
|
2011-10-20 05:43:48 +00:00
|
|
|
end
|
2012-05-12 08:40:04 +00:00
|
|
|
|
2012-12-13 06:38:15 +00:00
|
|
|
def context=(value)
|
|
|
|
@context = value
|
|
|
|
each {|item| item.context = value } if @decorated_collection
|
2012-05-08 15:44:50 +00:00
|
|
|
end
|
2012-01-27 19:40:49 +00:00
|
|
|
|
2013-02-06 13:05:40 +00:00
|
|
|
# @return [true]
|
|
|
|
def decorated?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2019-05-31 14:08:31 +00:00
|
|
|
alias :decorated_with? :instance_of?
|
2013-03-13 23:04:10 +00:00
|
|
|
|
2013-03-04 00:00:56 +00:00
|
|
|
def kind_of?(klass)
|
|
|
|
decorated_collection.kind_of?(klass) || super
|
|
|
|
end
|
2019-05-31 14:08:31 +00:00
|
|
|
|
2013-03-11 08:19:00 +00:00
|
|
|
alias_method :is_a?, :kind_of?
|
2013-03-04 00:00:56 +00:00
|
|
|
|
2013-04-15 21:46:19 +00:00
|
|
|
def replace(other)
|
|
|
|
decorated_collection.replace(other)
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2012-10-31 23:19:33 +00:00
|
|
|
protected
|
2012-10-31 22:27:40 +00:00
|
|
|
|
2013-01-07 16:33:24 +00:00
|
|
|
# Decorates the given item.
|
2012-11-07 21:35:02 +00:00
|
|
|
def decorate_item(item)
|
2013-03-10 07:47:53 +00:00
|
|
|
item_decorator.call(item, context: context)
|
2012-11-07 21:35:02 +00:00
|
|
|
end
|
|
|
|
|
2013-01-07 16:33:24 +00:00
|
|
|
private
|
|
|
|
|
2012-12-19 21:45:22 +00:00
|
|
|
def item_decorator
|
2013-02-15 08:03:08 +00:00
|
|
|
if decorator_class
|
2012-12-19 21:45:22 +00:00
|
|
|
decorator_class.method(:decorate)
|
2013-02-15 08:03:08 +00:00
|
|
|
else
|
2012-12-19 21:45:22 +00:00
|
|
|
->(item, options) { item.decorate(options) }
|
|
|
|
end
|
|
|
|
end
|
2011-10-20 05:43:48 +00:00
|
|
|
end
|
2011-10-20 21:22:05 +00:00
|
|
|
end
|