Class: SkullIsland::ResourceCollection

Inherits:
Object
  • Object
show all
Includes:
Comparable, Enumerable
Defined in:
lib/skull_island/resource_collection.rb

Overview

The ResourceCollection class Should not allow or use mixed types

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(list, options = {}) ⇒ ResourceCollection

Returns a new instance of ResourceCollection.



13
14
15
16
17
18
19
20
21
# File 'lib/skull_island/resource_collection.rb', line 13

def initialize(list, options = {})
  # TODO: better options validations
  raise Exceptions::InvalidOptions unless options.is_a?(Hash)
  raise Exceptions::InvalidArguments if list.empty? && options[:type].nil?

  @api_client = options[:api_client] || APIClient.instance
  @list = list
  @type = options[:type] || list.first.class
end

Instance Attribute Details

#typeClass (readonly)

Returns a collection of this SkullIsland::Resource subclass.

Returns:



11
12
13
# File 'lib/skull_island/resource_collection.rb', line 11

def type
  @type
end

Instance Method Details

#+(other) ⇒ ResourceCollection

Return a collection after adding to the original

Warning: this may cause duplicates or mixed type joins! For safety,
use #merge

Returns:



163
164
165
166
167
168
169
170
171
172
# File 'lib/skull_island/resource_collection.rb', line 163

def +(other)
  case other
  when self.class
    self.class.new(@list + other.to_a, type: @type, api_client: @api_client)
  when @type
    self.class.new(@list + [other], type: @type, api_client: @api_client)
  else
    raise Exceptions::InvalidArguments
  end
end

#-(other) ⇒ ResourceCollection

Return a collection after subtracting from the original

Returns:



149
150
151
152
153
154
155
156
157
# File 'lib/skull_island/resource_collection.rb', line 149

def -(other)
  if other.respond_to?(:to_a)
    self.class.new(@list - other.to_a, type: @type, api_client: @api_client)
  elsif other.is_a?(Resource)
    self.class.new(@list - Array(other), type: @type, api_client: @api_client)
  else
    raise Exceptions::InvalidArguments
  end
end

#<<(other) ⇒ Object



174
175
176
177
178
# File 'lib/skull_island/resource_collection.rb', line 174

def <<(other)
  raise Exceptions::InvalidArguments, 'Resource Type Mismatch' unless other.instance_of?(@type)

  @list << other
end

#<=>(other) ⇒ Object



180
181
182
# File 'lib/skull_island/resource_collection.rb', line 180

def <=>(other)
  collect(&:id).sort <=> other.collect(&:id).sort
end

#==(other) ⇒ Boolean

Allow comparison of collection

Returns:

  • (Boolean)

    do the collections contain the same resource ids?



186
187
188
189
190
191
192
# File 'lib/skull_island/resource_collection.rb', line 186

def ==(other)
  if other.is_a? self.class
    collect(&:id).sort == other.collect(&:id).sort
  else
    false
  end
end

#[](index) ⇒ Resource, ResourceCollection

Return the collection item at the specified index

Returns:



139
140
141
142
143
144
145
# File 'lib/skull_island/resource_collection.rb', line 139

def [](index)
  if index.is_a?(Range)
    self.class.new(@list[index], type: @type, api_client: @api_client)
  else
    @list[index]
  end
end

#each(&block) ⇒ Object



23
24
25
# File 'lib/skull_island/resource_collection.rb', line 23

def each(&block)
  @list.each(&block)
end

#empty?Boolean

Does the collection contain anything?

Returns:

  • (Boolean)


29
30
31
# File 'lib/skull_island/resource_collection.rb', line 29

def empty?
  @list.empty?
end

#first(number = nil) ⇒ ResourceCollection, Resource

Provide the first (or first ‘number`) entries

Parameters:

  • number (Fixnum) (defaults to: nil)

    How many to provide

Returns:



36
37
38
39
40
41
42
# File 'lib/skull_island/resource_collection.rb', line 36

def first(number = nil)
  if number
    self.class.new(@list.first(number), type: @type, api_client: @api_client)
  else
    @list.first
  end
end

#last(number = nil) ⇒ ResourceCollection, Resource

Provide the last (or last ‘number`) entries

Parameters:

  • number (Fixnum) (defaults to: nil)

    How many to provide

Returns:



47
48
49
50
51
52
53
# File 'lib/skull_island/resource_collection.rb', line 47

def last(number = nil)
  if number
    self.class.new(@list.last(number), type: @type, api_client: @api_client)
  else
    @list.last
  end
end

#merge(other) ⇒ ResourceCollection

Merge two collections

Parameters:

Returns:

Raises:



58
59
60
61
62
# File 'lib/skull_island/resource_collection.rb', line 58

def merge(other)
  raise Exceptions::InvalidArguments unless other.is_a?(self.class)

  self + (other - self)
end

#modelObject

An alias for #type



65
66
67
# File 'lib/skull_island/resource_collection.rb', line 65

def model
  type
end

#or(attribute, value, options = {}) ⇒ ResourceCollection

Hacked together #or() method in the same spirit as #where(). This method can be chained for multiple / more specific queries.

Parameters:

  • attribute (Symbol)

    the attribute to query

  • value (Object)

    the value to compare against

    • allowed options are “‘==’, ‘!=’, ‘>’, ‘>=’, ‘<’, ‘<=’, and ‘match’”

Returns:

Raises:



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/skull_island/resource_collection.rb', line 77

def or(attribute, value, options = {})
  options[:comparison] ||= value.is_a?(Regexp) ? :match : '=='
  if empty?
    @type.where(attribute, value, comparison: options[:comparison], api_client: @api_client)
  else
    merge first.class.where(
      attribute, value,
      comparison: options[:comparison],
      api_client: @api_client
    )
  end
end

#paginate(*args) ⇒ Object

Pass pagination through to the Array (which passes to will_paginate)



91
92
93
# File 'lib/skull_island/resource_collection.rb', line 91

def paginate(*args)
  @list.paginate(*args)
end

#sizeFixnum

Returns the number of Resource instances in the collection

Returns:

  • (Fixnum)


97
98
99
# File 'lib/skull_island/resource_collection.rb', line 97

def size
  @list.size
end

#sort(&block) ⇒ ResourceCollection

Allow complex sorting like an Array

Returns:



103
104
105
# File 'lib/skull_island/resource_collection.rb', line 103

def sort(&block)
  self.class.new(super(&block), type: @type, api_client: @api_client)
end

#where(attribute, value, options = {}) ⇒ ResourceCollection Also known as: and

Horribly inefficient way to allow querying Resources by their attributes. This method can be chained for multiple / more specific queries.

Parameters:

  • attribute (Symbol)

    the attribute to query

  • value (Object)

    the value to compare against

    • allowed options are “‘==’, ‘!=’, ‘>’, ‘>=’, ‘<’, ‘<=’, and ‘match’”

Returns:

Raises:



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/skull_island/resource_collection.rb', line 115

def where(attribute, value, options = {})
  valid_comparisons = %i[== != > >= < <= match]
  options[:comparison] ||= value.is_a?(Regexp) ? :match : '=='
  unless valid_comparisons.include?(options[:comparison].to_sym)
    raise Exceptions::InvalidWhereQuery
  end

  self.class.new(
    @list.collect do |item|
      if item.send(attribute).nil?
        nil
      elsif item.send(attribute).send(options[:comparison].to_sym, value)
        item
      end
    end.compact,
    type: @type,
    api_client: @api_client
  )
end