Class: Miscellany::SlicedResponse::Slice

Inherits:
Object
  • Object
show all
Defined in:
lib/miscellany/controller/sliced_response.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(items, options = {}) ⇒ Slice

Returns a new instance of Slice.



76
77
78
79
# File 'lib/miscellany/controller/sliced_response.rb', line 76

def initialize(items, options={})
  @items = items
  @options = options
end

Instance Attribute Details

#itemsObject (readonly)

Returns the value of attribute items.



73
74
75
# File 'lib/miscellany/controller/sliced_response.rb', line 73

def items
  @items
end

#optionsObject (readonly)

Returns the value of attribute options.



74
75
76
# File 'lib/miscellany/controller/sliced_response.rb', line 74

def options
  @options
end

#page_numberObject

Returns the value of attribute page_number.



70
71
72
# File 'lib/miscellany/controller/sliced_response.rb', line 70

def page_number
  @page_number
end

#page_sizeObject

Returns the value of attribute page_size.



70
71
72
# File 'lib/miscellany/controller/sliced_response.rb', line 70

def page_size
  @page_size
end

#slice_endObject

Returns the value of attribute slice_end.



69
70
71
# File 'lib/miscellany/controller/sliced_response.rb', line 69

def slice_end
  @slice_end
end

#slice_startObject

Returns the value of attribute slice_start.



69
70
71
# File 'lib/miscellany/controller/sliced_response.rb', line 69

def slice_start
  @slice_start
end

#sortObject

Returns the value of attribute sort.



71
72
73
# File 'lib/miscellany/controller/sliced_response.rb', line 71

def sort
  @sort
end

Class Method Details

.build(queryset, arg, options = {}) ⇒ Object



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
116
117
118
119
120
# File 'lib/miscellany/controller/sliced_response.rb', line 81

def self.build(queryset, arg, options={})
  new(queryset, options).tap do |slice|
    if arg.is_a?(Array)
      slice_bounds = arg
    elsif arg.is_a?(String)
      slice_bounds = arg.split(':').map(&:to_i)
    elsif arg.is_a?(Range)
      slice_bounds = arg.minmax
    elsif arg.respond_to? :[]
      if arg[:slice] == 'all' || arg[:page] == 'all'
        slice_bounds = [0, -1]
      elsif arg[:slice].present?
        slice_bounds = arg[:slice].split(':').map(&:to_i)
      else
        page_size = slice[:page_size] = (arg[:page_size] || options[:default_page_size]).to_i
        page_number = slice[:page_number] = (arg[:page] || 1).to_i
        slice_bounds = [(page_number - 1) * page_size, page_number * page_size]
      end

      begin
        slice[:sort] = options[:sort_parser]&.parse(arg[:sort], ignore_errors: true, default: true)
      rescue Miscellany::SortLang::Parser::SortParsingError => e
        raise HttpErrorHandling::HttpError, message: e.message
      end
    end

    if slice_bounds.present?
      slice[:slice_start] = slice_bounds[0]
      slice[:slice_end] = slice_bounds[1]
    end

    if slice[:slice_end] == -1
      raise HttpErrorHandling::HttpError, message: "cannot request whole collection" unless options[:allow_all]
    else
      if options[:max_size] && (slice[:slice_end] - slice[:slice_start]) > [options[:max_size], options[:default_size]].max
        raise HttpErrorHandling::HttpError, message: "cannot request more than #{options[:max_size]} objects"
      end
    end
  end
end

Instance Method Details

#[](key) ⇒ Object



122
123
124
# File 'lib/miscellany/controller/sliced_response.rb', line 122

def [](key)
  send(key)
end

#[]=(key, val) ⇒ Object



126
127
128
# File 'lib/miscellany/controller/sliced_response.rb', line 126

def []=(key, val)
  send(:"#{key}=", val)
end

#render_jsonObject



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/miscellany/controller/sliced_response.rb', line 130

def render_json
  return @rendered_json if defined?(@rendered_json)

  json = @rendered_json = {
    slice_start: slice_start,
    slice_end: slice_end,
  }

  rendered_items

  if page_size.present?
    json[:page] ||= page_number
    json[:page_size] ||= page_size
  end

  if total_item_count.present?
    json[:total_count] ||= total_item_count
    json[:page_count] ||= (total_item_count.to_f / page_size).ceil if page_size.present?
  end

  if sort.present?
    json[:sort] ||= sort.map do |s|
      "#{s[:key] || s[:column]} #{s[:order] || 'ASC'}"
    end.join(', ')
  end

  json[:slice_start] ||= 0
  json[:slice_end] ||= total_item_count

  json[:items] = rendered_items

  json
end

#rendered_jsonObject



163
# File 'lib/miscellany/controller/sliced_response.rb', line 163

def rendered_json; render_json; end