Class: Hook::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/hook-client/collection.rb

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Collection

Returns a new instance of Collection.



4
5
6
7
8
9
10
11
# File 'lib/hook-client/collection.rb', line 4

def initialize options = {}
  @name = options.delete(:name)
  @client = options.delete(:client) || Hook::Client.instance

  segment = options.delete(:channel) ? "channel" : "collection"
  @segments = "#{segment}/#{@name}"
  reset!
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



156
157
158
159
160
161
162
# File 'lib/hook-client/collection.rb', line 156

def method_missing method, *args, &block
  if Enumerator.method_defined? method
    Enumerator.new(self.all).send(method, args, block)
  end

  throw NoMethodError.new("#{self.class.name}: method '#{method}' not found")
end

Instance Method Details

#all { ... } ⇒ Array

Run the query, and return all it’s results.

Yields:

  • You may use a block with all returned results

Returns:

  • (Array)


146
147
148
149
150
# File 'lib/hook-client/collection.rb', line 146

def all(&block)
  rows = query!
  yield rows if block_given?
  rows
end

#avg(field) ⇒ Object



218
219
220
221
# File 'lib/hook-client/collection.rb', line 218

def avg field
  @options[:aggregation] = { :method => :avg, :field => field }
  self.query!
end

#build_queryObject



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/hook-client/collection.rb', line 247

def build_query
  query = {}
  query[:limit] = @limit if @limit
  query[:offset] = @offset if @offset

  query[:q] = @wheres unless @wheres.empty?
  query[:s] = @ordering unless @ordering.empty?
  query[:g] = @group unless @group.empty?

  {
    :paginate => 'p',
    :first => 'f',
    :aggregation => 'aggr',
    :operation => 'op',
    :data => 'data',
    :with => 'with',
    :select => 'select',
  }.each_pair do |option, shortname|
    query[ shortname ] = @options[ option ] if @options[ option ]
  end

  self.reset!
  query
end

#count(field = '*') ⇒ Object



203
204
205
206
# File 'lib/hook-client/collection.rb', line 203

def count field = '*'
  @options[:aggregation] = { :method => 'count', :field => field }
  self.query!
end

#create(data) ⇒ Hash, Array

Create an item into the collection

Parameters:

  • data (Hash, Array)

    item or array of items

Returns:

  • (Hash, Array)


35
36
37
38
39
40
41
42
43
# File 'lib/hook-client/collection.rb', line 35

def create data
  if data.kind_of?(Array)
    # TODO: server should accept multiple items to create,
    # instead of making multiple requests.
    data.map {|item| self.create(item) }
  else
    @client.post @segments, data
  end
end

#decrement(field, value = 1) ⇒ Object



233
234
235
236
# File 'lib/hook-client/collection.rb', line 233

def decrement field, value = 1
  @options[:operation] =  { :method => 'decrement', :field => field, :value => value }
  self.query!
end

#delete_allObject

Remove items by query. This is the same as calling ‘remove` without `_id` param.

See Also:



68
69
70
# File 'lib/hook-client/collection.rb', line 68

def delete_all
  self.remove(nil)
end

#find(_id) ⇒ Hash

Find item by _id.

Parameters:

  • _id (String)

Returns:

  • (Hash)


17
18
19
20
21
22
23
# File 'lib/hook-client/collection.rb', line 17

def find _id
  if _id.kind_of?(Array)
    self.where(:_id.in => _id).all
  else
    @client.get "#{@segments}/#{_id}"
  end
end

#firstObject

Return only the first result from the database



26
27
28
29
# File 'lib/hook-client/collection.rb', line 26

def first
  @options[:first] = 1
  self.query!
end

#first_or_create(data) ⇒ Hash

Retrieve the first item with the given params in the database, if not found this will create one.

Parameters:

  • data (Hash)

    query and data to store

Returns:

  • (Hash)


50
51
52
53
54
# File 'lib/hook-client/collection.rb', line 50

def first_or_create data
  @options[:first] = 1
  @options[:data] = data
  @client.post(@segments, self.build_query)
end

#group(*fields) ⇒ Collection

Group query results

Parameters:

  • fields (String)

Returns:



198
199
200
201
# File 'lib/hook-client/collection.rb', line 198

def group *fields
  @group = fields
  self
end

#increment(field, value = 1) ⇒ Object



228
229
230
231
# File 'lib/hook-client/collection.rb', line 228

def increment field, value = 1
  @options[:operation] =  { :method => 'increment', :field => field, :value => value }
  self.query!
end

#limit(int) ⇒ Collection

Limit the number of results to retrieve.

Parameters:

  • int (Integer)

Returns:



131
132
133
134
# File 'lib/hook-client/collection.rb', line 131

def limit int
  @limit = int
  self
end

#max(field) ⇒ Object



208
209
210
211
# File 'lib/hook-client/collection.rb', line 208

def max field
  @options[:aggregation] = { :method => :max, :field => field }
  self.query!
end

#min(field) ⇒ Object



213
214
215
216
# File 'lib/hook-client/collection.rb', line 213

def min field
  @options[:aggregation] = { :method => :min, :field => field }
  self.query!
end

#offset(int) ⇒ Collection

Returns self.

Parameters:

  • int (Integer)

Returns:



138
139
140
141
# File 'lib/hook-client/collection.rb', line 138

def offset int
  @offset = int
  self
end

#or_where(fields = {}) ⇒ Collection

Add where clause with ‘OR’ operation to the current query.

Parameters:

  • fields (Hash) (defaults to: {})

    fields and values to filter

Returns:



108
109
110
# File 'lib/hook-client/collection.rb', line 108

def or_where fields = {}
  self.where(fields, 'or')
end

#order(fields) ⇒ Collection Also known as: sort

Add order clause to the query.

Parameters:

  • fields (String)

Returns:



116
117
118
119
120
121
122
123
124
# File 'lib/hook-client/collection.rb', line 116

def order fields
  by_num = { 1 => 'asc', -1 => 'desc' }
  ordering = []
  fields.each_pair do |key, value|
    ordering << [key.to_s, by_num[value] || value]
  end
  @ordering = ordering
  self
end

#query!Object



152
153
154
# File 'lib/hook-client/collection.rb', line 152

def query!
  @client.get @segments, build_query
end

#remove(_id = nil) ⇒ Hash

Remove items by id, or by query

Parameters:

  • _id (String, nil) (defaults to: nil)

    _id

Returns:

  • (Hash)

    status of the operation (ex: true, affected_rows: 7)



60
61
62
63
64
# File 'lib/hook-client/collection.rb', line 60

def remove _id = nil
  path = @segments
  path = "#{path}/#{_id}" if _id
  @client.remove(path, build_query)
end

#select(*fields) ⇒ Collection

Specify the target field names to retrieve

Parameters:

  • fields (String)

Returns:



168
169
170
# File 'lib/hook-client/collection.rb', line 168

def select *fields
  @options[:select] = fields
end

#sum(field) ⇒ Object



223
224
225
226
# File 'lib/hook-client/collection.rb', line 223

def sum field
  @options[:aggregation] = { :method => :sum, :field => field }
  self.query!
end

#update(_id, data) ⇒ Object



238
239
240
# File 'lib/hook-client/collection.rb', line 238

def update _id, data
  @client.post "#{@segments}/#{_id}", data
end

#update_all(data) ⇒ Object



242
243
244
245
# File 'lib/hook-client/collection.rb', line 242

def update_all data
  @options[:data] = data
  @client.put @segments, build_query
end

#where(fields = {}, operation = 'and') ⇒ Collection

Add where clause to the current query.

Supported modifiers on fields: .gt, .gte, .lt, .lte, .ne, .in, .not_in, .nin, .like, .between, .not_between

Examples:

hook.collection(:movies).where({
  :name => "Hook",
  :year.gt => 1990
})

Using Range

hook.collection(:movies).where({
  :name.like => "%panic%",
  :year.between => 1990..2014
})

Parameters:

  • fields (Hash) (defaults to: {})

    fields and values to filter

  • operation (String) (defaults to: 'and')

    (and, or)

Returns:



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/hook-client/collection.rb', line 92

def where fields = {}, operation = 'and'
  fields.each_pair do |k, value|
    field = (k.respond_to?(:field) ? k.field : k).to_s
    comparation = k.respond_to?(:comparation) ? k.comparation : '='

    # Range syntatic sugar
    value = [ value.first, value.last ] if value.kind_of?(Range)

    @wheres << [field, comparation, value, operation]
  end
  self
end

#with(*relationships) ⇒ Collection

Return related collection’s data

Examples:

Retrieving a single relation

hook.collection(:books).with(:publisher).each do |book|
  puts book[:name]
  puts book[:publisher][:name]
end

Retrieving multiple relations

hook.collection(:books).with(:publisher, :author).each do |book|
  puts book[:name]
  puts book[:publisher][:name]
  puts book[:author][:name]
end

Parameters:

  • relationships (String)

Returns:



190
191
192
193
# File 'lib/hook-client/collection.rb', line 190

def with *relationships
  @options[:with] = relationships
  self
end