Class: Brainstem::PresenterCollection

Inherits:
Object
  • Object
show all
Defined in:
lib/brainstem/presenter_collection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#default_max_per_pageInteger

Returns The maximum number of objects that can be requested in a single presented hash.

Returns:

  • The maximum number of objects that can be requested in a single presented hash.



9
10
11
# File 'lib/brainstem/presenter_collection.rb', line 9

def default_max_per_page
  @default_max_per_page
end

#default_per_pageInteger

Returns The default number of objects that will be returned in the presented hash.

Returns:

  • The default number of objects that will be returned in the presented hash.



13
14
15
# File 'lib/brainstem/presenter_collection.rb', line 13

def default_per_page
  @default_per_page
end

Instance Method Details

#add_presenter_class(presenter_class, *klasses) ⇒ Object

Parameters:

  • The presenter class that knows how to present all of the classes given in klasses.

  • One or more classes that can be presented by presenter_class.



124
125
126
127
128
# File 'lib/brainstem/presenter_collection.rb', line 124

def add_presenter_class(presenter_class, *klasses)
  klasses.each do |klass|
    presenters[klass.to_s] = presenter_class.new
  end
end

#for(klass) ⇒ Brainstem::Presenter?

Returns The presenter that knows how to present the class klass, or nil if there isn’t one.

Returns:

  • The presenter that knows how to present the class klass, or nil if there isn’t one.



131
132
133
# File 'lib/brainstem/presenter_collection.rb', line 131

def for(klass)
  presenters[klass.to_s]
end

#for!(klass) ⇒ Brainstem::Presenter

Returns The presenter that knows how to present the class klass.

Returns:

  • The presenter that knows how to present the class klass.

Raises:

  • if there is no known presenter for klass.



137
138
139
# File 'lib/brainstem/presenter_collection.rb', line 137

def for!(klass)
  self.for(klass) || raise(ArgumentError, "Unable to find a presenter for class #{klass}")
end

#presentersHash

Returns The presenters this collection knows about, keyed on the names of the classes that can be presented.

Returns:

  • The presenters this collection knows about, keyed on the names of the classes that can be presented.



118
119
120
# File 'lib/brainstem/presenter_collection.rb', line 118

def presenters
  @presenters ||= {}
end

#presenting(name, options = {}) { ... } ⇒ Hash

The main presentation method, converting a model name and an optional scope into a hash structure, ready to be converted into JSON. If searching, Brainstem filtering, only, pagination, and ordering are skipped and should be implemented with your search solution. All request options are passed to the search_block for your convenience.

Parameters:

  • The class of the objects to be presented.

  • (defaults to: {})

    The options that will be applied as the objects are converted.

Options Hash (options):

  • :params (Hash)

    The params hash included in a request for the presented object.

  • :model (ActiveRecord::Base)

    The model that is being presented (if different from name).

  • :as (String)

    The top-level key the presented objects will be assigned to (if different from name.tableize)

  • :max_per_page (Integer)

    The maximum number of items that can be requested by params[:per_page].

  • :per_page (Integer)

    The number of items that will be returned if params[:per_page] is not set.

  • :apply_default_filters (Boolean)

    Determine if Presenter’s filter defaults should be applied. On by default.

Yields:

  • Must return a scope on the model name, which will then be presented.

Returns:

  • A hash of arrays of hashes. Top-level hash keys are pluralized model names, with values of arrays containing one hash per object that was found by the given given options.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/brainstem/presenter_collection.rb', line 34

def presenting(name, options = {}, &block)
  options[:params] = HashWithIndifferentAccess.new(options[:params] || {})
  presented_class = (options[:model] || name)
  presented_class = presented_class.classify.constantize if presented_class.is_a?(String)
  scope = presented_class.instance_eval(&block)
  count = 0

  # grab the presenter that knows about filters and sorting etc.
  options[:presenter] = for!(presented_class)

  # table name will be used to query the database for the filtered data
  options[:table_name] = presented_class.table_name

  # key these models will use in the struct that is output
  options[:as] = (options[:as] || name.to_s.tableize).to_sym

  allowed_includes = calculate_allowed_includes options[:presenter], presented_class, options[:params][:only].present?
  includes_hash = filter_includes options[:params][:include], allowed_includes

  if searching? options
    # Search
    sort_name, direction = calculate_sort_name_and_direction options
    scope, count, ordered_search_ids = run_search(scope, includes_hash.keys.map(&:to_s), sort_name, direction, options)
  else
    # Filter
    scope = run_filters scope, options

    if options[:params][:only].present?
      # Handle Only
      scope, count = handle_only(scope, options[:params][:only])
    else
      # Paginate
      scope, count = paginate scope, options
    end

    count = count.keys.length if count.is_a?(Hash)

    # Ordering
    scope = handle_ordering scope, options
  end

  # Load Includes
  records = scope.to_a

  # Determine if an exception should be raised on an empty result set.
  if options[:raise_on_empty] && records.empty?
    raise options[:empty_error_class] || ActiveRecord::RecordNotFound
  end

  records = order_for_search(records, ordered_search_ids) if searching? options
  model = records.first

  models = perform_preloading records, includes_hash
  primary_models, associated_models = gather_associations(models, includes_hash)
  struct = { :count => count, options[:as] => [], :results => [] }

  associated_models.each do |json_name, models|
    models.flatten!
    models.uniq!

    if models.length > 0
      presenter = for!(models.first.class)
      assoc = includes_hash.to_a.find { |k, v| v.json_name == json_name }
      struct[json_name] = presenter.group_present(models, [])
    else
      struct[json_name] = []
    end
  end

  if primary_models.length > 0
    presented_primary_models = options[:presenter].group_present(models, includes_hash.keys)
    struct[options[:as]] += presented_primary_models
    struct[:results] = presented_primary_models.map { |model| { :key => options[:as].to_s, :id => model[:id] } }
  end

  rewrite_keys_as_objects!(struct)

  # Make struct pretty-print when rendered as json, if required.
  make_pretty_printable!(struct) if options[:params][:pretty] == "true"

  struct
end