app/presenters/counters_presenter.rb

Summary

Maintainability
A
0 mins
Test Coverage
class CountersPresenter
  include Presenter

  required_keys :object, :ctx

  AVAILABLE_COUNTERS = [:geo_data, :maps, :followers, :contributors]

  def counters
    AVAILABLE_COUNTERS.map { |name|
      OpenStruct.new(counter_options name)
    }.select { |counter|
      object.respond_to? counter[:method]
    }
  end

  def counter_options(name)
    opts = send(:"_#{name}_counter")
    _count = object.try(opts[:method]) || 0
    opts.merge!({ url: counter_url(opts[:url_params]) }) if object.respond_to? opts[:method]
    opts.merge({
      count: _count,
      classname: "#{opts[:classname]} #{size_}",
      value: (size_ == :big) ? ctx.t(opts[:string], count: "<em class=\"counter-label\">#{_count}</em>") : "<span class=\"counter-label\">#{_count}</span>"
    })
  end

  def size_
    @size || :medium
  end

  private

    def counter_url(params)
      begin
        ctx.url_for(params)
      rescue Exception
        ctx.url_for(params.reverse)
      end
    end

    def _geo_data_counter
      {
        icon:       :'map-marker',
        string:     'counters.geo_data',
        method:     :geo_data_count,
        classname:  "geo_data-counter",
        url_params: [:geo_data, object],
        component:  _component_for('geo_data')
      }
    end

    def _maps_counter
      {
        icon:       :globe,
        string:     'counters.maps',
        method:     :maps_count,
        classname:  "maps-counter",
        url_params: [:maps, object],
        component:  _component_for('maps')
      }
    end

    def _followers_counter
      {
        icon:       :star,
        string:     'counters.followers',
        method:     :followers_count,
        classname:  "followers-counter",
        url_params: [object, :followers],
        component:  _component_for('followers')
      }
    end

    def _contributors_counter
      {
        icon:       :users,
        string:     'counters.contributors',
        method:     :contributors_count,
        classname:  "contributors-counter",
        url_params: [object, :contributors]
      }
    end

    def _component_for(type)
      opts_json = {type: type, id: ctx.identifier_for(object)}.to_json
      {
        :type => "counter",
        :opts => "data-counter-options=#{ opts_json } "
      }
    end
end