Sha256: 05c786d17858db9dabeeba9a64a9797fd3e09e407e5b832fe13fc636eb50e420

Contents?: true

Size: 1.97 KB

Versions: 71

Compression:

Stored size: 1.97 KB

Contents

# frozen_string_literal: true

class CollectionPresenter
  # Initialises an enumerable collection of initialised presenters for the
  # corresponding original_collection of objects, for example a collection
  # of Letter objects.
  #
  # The *options catches:
  # - presenter_class, optional
  # - view_context, optional
  #
  # It is written this way because I needed to add an optional view_context
  # (which some Presenters may need) without breaking existing usage.
  def initialize(original_collection, *options)
    @original_collection = original_collection
    presenter_class, view_context = parse_options(options, block_given?)

    @decorated_collection ||= Enumerator.new do |yielder|
      original_collection.each do |element|
        presenter = if block_given?
                      yield(element)
                    else
                      build_presenter(presenter_class, element, view_context)
                    end
        yielder.yield(presenter)
      end
    end
  end

  def to_ary
    @decorated_collection.to_a
  end

  def to_a
    @decorated_collection.to_a
  end

  delegate :size, to: :to_ary

  def to_json
    @decorated_collection.map(&:to_hash).to_json
  end

  def method_missing(method, *args, &block)
    if @decorated_collection.respond_to?(method)
      @decorated_collection.public_send(method, *args, &block)
    else
      @original_collection.public_send(method, *args, &block)
    end
  end

  def respond_to?(method)
    @decorated_collection.respond_to?(method) || @original_collection.respond_to?(method)
  end

  private

  def parse_options(options, block_given)
    options = Array(options)
    if options.empty? && !block_given
      raise "A presenter class must be supplied if no block given"
    end

    presenter_class = options[0]
    view_context = options[1]
    [presenter_class, view_context]
  end

  def build_presenter(klass, element, view_context)
    args = [element]
    args << view_context if view_context.present?
    klass.new(*args)
  end
end

Version data entries

71 entries across 71 versions & 1 rubygems

Version Path
renalware-core-2.0.124 lib/collection_presenter.rb
renalware-core-2.0.123 lib/collection_presenter.rb
renalware-core-2.0.121 lib/collection_presenter.rb
renalware-core-2.0.120 lib/collection_presenter.rb
renalware-core-2.0.119 lib/collection_presenter.rb
renalware-core-2.0.118 lib/collection_presenter.rb
renalware-core-2.0.117 lib/collection_presenter.rb
renalware-core-2.0.116 lib/collection_presenter.rb
renalware-core-2.0.115 lib/collection_presenter.rb
renalware-core-2.0.113 lib/collection_presenter.rb
renalware-core-2.0.112 lib/collection_presenter.rb
renalware-core-2.0.111 lib/collection_presenter.rb
renalware-core-2.0.110 lib/collection_presenter.rb
renalware-core-2.0.109 lib/collection_presenter.rb
renalware-core-2.0.108 lib/collection_presenter.rb
renalware-core-2.0.106 lib/collection_presenter.rb
renalware-core-2.0.105 lib/collection_presenter.rb
renalware-core-2.0.104 lib/collection_presenter.rb
renalware-core-2.0.103 lib/collection_presenter.rb
renalware-core-2.0.102 lib/collection_presenter.rb