Class: Parse::Query

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks
Includes:
Enumerable, Client::Connectable
Defined in:
lib/parse/query.rb,
lib/parse/model/core/actions.rb

Overview

The Query class provides the lower-level querying interface for your Parse collections by utilizing the REST Querying interface. This is the main engine behind making Parse queries on remote collections. It takes a set of constraints and generates the proper hash parameters that are passed to an API request in order to retrive matching results. The querying design pattern is inspired from DataMapper where symbols are overloaded with specific methods with attached values.

At the core of each item is a Operation. An operation is made up of a field name and an operator. Therefore calling something like :name.eq, defines an equality operator on the field name. Using Operations with values, we can build different types of constraints, known as Constraints.

This component can be used on its own without defining your models as all results are provided in hash form.

Field-Formatter

By convention in Ruby (see Style Guide), symbols and variables are expressed in lower_snake_case form. Parse, however, prefers column names in String#columnize format (ex. `objectId`, `createdAt` and `updatedAt`). To keep in line with the style guides between the languages, we do the automatic conversion of the field names when compiling the query. This feature can be overridden by changing the value of Query.field_formatter.

# default uses :columnize
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
query.compile_where # => {"fieldOne"=>1, "fieldTwo"=>2, "fieldThree"=>3}

# turn off
Parse::Query.field_formatter = nil
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
query.compile_where # => {"field_one"=>1, "FieldTwo"=>2, "Field_Three"=>3}

# force everything camel case
Parse::Query.field_formatter = :camelize
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
query.compile_where # => {"FieldOne"=>1, "FieldTwo"=>2, "FieldThree"=>3}

Most of the constraints supported by Parse are available to `Parse::Query`. Assuming you have a column named `field`, here are some examples. For an explanation of the constraints, please see Parse Query Constraints documentation. You can build your own custom query constraints by creating a `Parse::Constraint` subclass. For all these `where` clauses assume `q` is a `Parse::Query` object.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#new(table) ⇒ Query #new(parseSubclass) ⇒ Query

Constructor method to create a query with constraints for a specific Parse collection. Also sets the default limit count to `:max`.

Overloads:

  • #new(table) ⇒ Query

    Create a query for this Parse collection name.

    Examples:

    Parse::Query.new "_User"
    Parse::Query.new "_Installation", :device_type => 'ios'

    Parameters:

    • table (String)

      the name of the Parse collection to query. (ex. “_User”)

    • constraints (Hash)

      a set of query constraints.

  • #new(parseSubclass) ⇒ Query

    Create a query for this Parse model (or anything that responds to Object.parse_class).

    Examples:

    Parse::Query.new Parse::User
    # assume Post < Parse::Object
    Parse::Query.new Post, like_count.gt => 0

    Parameters:

    • parseSubclass (Parse::Object)

      the Parse model constant

    • constraints (Hash)

      a set of query constraints.

Raises:

  • (ArgumentError)

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/parse/query.rb', line 287

def initialize(table, constraints = {})
  table = table.to_s.to_parse_class if table.is_a?(Symbol)
  table = table.parse_class if table.respond_to?(:parse_class)
  raise ArgumentError, "First parameter should be the name of the Parse class (table)" unless table.is_a?(String)
  @count = 0 #non-zero/1 implies a count query request
  @where = []
  @order = []
  @keys = []
  @includes = []
  @limit = nil
  @skip = 0
  @table = table
  @cache = true
  @use_master_key = true
  conditions constraints
end

Class Attribute Details

.allow_scope_introspectionSymbol

The method to use when converting field names to Parse column names. Default is String#columnize. By convention Parse uses lowercase-first camelcase syntax for field/column names, but ruby uses snakecase. To support this methodology we process all field constraints through the method defined by the field formatter. You may set this to nil to turn off this functionality.

Returns:

# File 'lib/parse/query.rb', line 168

.field_formatterSymbol

The method to use when converting field names to Parse column names. Default is String#columnize. By convention Parse uses lowercase-first camelcase syntax for field/column names, but ruby uses snakecase. To support this methodology we process all field constraints through the method defined by the field formatter. You may set this to nil to turn off this functionality.

Returns:


182
183
184
# File 'lib/parse/query.rb', line 182

def field_formatter
  @field_formatter
end

Instance Attribute Details

#cacheBoolean, Integer

Set whether this query should be cached and for how long. This parameter is used to cache queries when using Middleware::Caching. If the caching middleware is configured, all queries will be cached for the duration allowed by the cache, and therefore some queries could return cached results. To disable caching and cached results for this specific query, you may set this field to `false`. To specify the specific amount of time you want this query to be cached, set a duration (in number of seconds) that the caching middleware should cache this request.

Examples:

# find all users with name "Bob"
query = Parse::Query.new("_User", :name => "Bob")

query.cache = true # (default) cache using default cache duration.

query.cache = 1.day # cache for 86400 seconds

query.cache = false # do not cache or use cache results

# You may optionally pass this into the constraint hash.
query = Parse::Query.new("_User", :name => "Bob", :cache => 1.day)

Returns:

  • (Boolean)

    if set to true or false on whether it should use the default caching length set when configuring Middleware::Caching.

  • (Integer)

    if set to a number of seconds to cache this specific request with the Middleware::Caching.


152
# File 'lib/parse/query.rb', line 152

attr_accessor :table, :client, :key, :cache, :use_master_key, :session_token

#clientParse::Client

Returns the client to use for making the API request.

Returns:

  • (Parse::Client)

    the client to use for making the API request.

See Also:


152
# File 'lib/parse/query.rb', line 152

attr_accessor :table, :client, :key, :cache, :use_master_key, :session_token

#keyString

This parameter is used to support `select` queries where you have to pass a `key` parameter for matching different tables.

Returns:

  • (String)

    the foreign key to match against.


152
# File 'lib/parse/query.rb', line 152

attr_accessor :table, :client, :key, :cache, :use_master_key, :session_token

#session_tokenString

Note:

Using a session_token automatically disables sending the master key in the request.

Set the session token to send with this API request. A session token is tied to a logged in User. When sending a session_token in the request, this performs the query on behalf of the user (with their allowed privileges). Using the short hand (inline) form, you can also pass an authenticated User instance or a Session instance.

Examples:

# perform this query as user represented by session_token
query = Parse::Query.new("_User", :name => "Bob")
query.session_token = "r:XyX123..."

# or inline
query = Parse::Query.new("_User", :name => "Bob", :session => "r:XyX123...")

# or with a logged in user object
user = Parse::User.('user','pass') # => logged in user'
user.session_token # => "r:XyZ1234...."
query = Parse::Query.new("_User", :name => "Bob", :session => user)

Returns:

  • (String)

    the session token to send with this API request.

Raises:

  • ArgumentError if a non-nil value is passed that doesn't provide a session token string.


152
# File 'lib/parse/query.rb', line 152

attr_accessor :table, :client, :key, :cache, :use_master_key, :session_token

#tableString

Returns the name of the Parse collection to query against.

Returns:

  • (String)

    the name of the Parse collection to query against.


152
153
154
# File 'lib/parse/query.rb', line 152

def table
  @table
end

#use_master_keyBoolean

True or false on whether we should send the master key in this request. If You have provided the master_key when initializing Parse, then all requests will send the master key by default. This feature is useful when you want to make a particular query be performed with public credentials, or on behalf of a user using a #session_token. Default is set to true.

Examples:

# disable use of the master_key in the request.
query = Parse::Query.new("_User", :name => "Bob", :master_key => false)

Returns:

  • (Boolean)

    whether we should send the master key in this request.

See Also:


152
# File 'lib/parse/query.rb', line 152

attr_accessor :table, :client, :key, :cache, :use_master_key, :session_token

Class Method Details

.all(table, constraints = {limit: :max}) ⇒ Query

Helper method to create a query with constraints for a specific Parse collection. Also sets the default limit count to `:max`.

Parameters:

  • table (String)

    the name of the Parse collection to query. (ex. “_User”)

  • constraints (Hash) (defaults to: {limit: :max})

    a set of query constraints.

Returns:

  • (Query)

    a new query for the Parse collection with the passed in constraints.


199
200
201
# File 'lib/parse/query.rb', line 199

def all(table, constraints = {limit: :max})
  self.new(table, constraints.reverse_merge({limit: :max}))
end

.compile_where(where) ⇒ Hash

This methods takes a set of constraints and merges them to build a final `where` constraint clause for sending to the Parse backend.

Parameters:

Returns:

  • (Hash)

    a hash representing the compiled query


207
208
209
# File 'lib/parse/query.rb', line 207

def compile_where(where)
  constraint_reduce( where )
end

.format_field(str) ⇒ String

Returns formatted string using field_formatter.

Parameters:

  • str (String)

    the string to format

Returns:


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

def format_field(str)
  res = str.to_s.strip
  if field_formatter.present? && res.respond_to?(field_formatter)
    res = res.send(field_formatter)
  end
  res
end

Instance Method Details

#add_constraint(operator, value = nil, **opts) ⇒ self

Add a constraint to the query. This is mainly used internally for compiling constraints.

Examples:

# add where :field equals "value"
query.add_constraint(:field.eq, "value")

# add where :like_count is greater than 20
query.add_constraint(:like_count.gt, 20)

Parameters:

  • operator (Parse::Operator)

    an operator object containing the operation and operand.

  • value (Object) (defaults to: nil)

    the value for the constraint.

Returns:

  • (self)

503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
# File 'lib/parse/query.rb', line 503

def add_constraint(operator, value = nil, **opts)
  @where ||= []
  constraint = operator # assume Parse::Constraint
  unless constraint.is_a?(Parse::Constraint)
    constraint = Parse::Constraint.create(operator, value)
  end
  return unless constraint.is_a?(Parse::Constraint)
  # to support select queries where you have to pass a `key` parameter for matching
  # different tables.
  if constraint.operand == :key || constraint.operand == "key"
    @key = constraint.value
    return
  end

  unless opts[:filter] == false
    constraint.operand = Query.format_field(constraint.operand)
  end
  @where.push constraint
  @results = nil
  self #chaining
end

#add_constraints(list) ⇒ self

Combine a list of Constraint objects

Parameters:

Returns:

  • (self)

486
487
488
489
490
# File 'lib/parse/query.rb', line 486

def add_constraints(list)
  list = Array.wrap(list).select { |m| m.is_a?(Parse::Constraint) }
  @where = @where + list
  self
end

#after_prepare { ... } ⇒ Object

A callback called after the query is compiled

Yields:

  • A block to execute for the callback.

See Also:

  • ActiveModel::Callbacks

79
# File 'lib/parse/query.rb', line 79

define_model_callbacks :prepare, only: [:after, :before]

#as_json(*args) ⇒ Hash

Returns:


804
805
806
# File 'lib/parse/query.rb', line 804

def as_json(*args)
  compile.as_json
end

#before_prepare { ... } ⇒ Object

A callback called before the query is compiled

Yields:

  • A block to execute for the callback.

See Also:

  • ActiveModel::Callbacks

79
# File 'lib/parse/query.rb', line 79

define_model_callbacks :prepare, only: [:after, :before]

#clause(clause_name = :where) ⇒ Object

returns the query clause for the particular clause

Parameters:

  • clause_name (Symbol) (defaults to: :where)

    One of supported clauses to return: :keys, :where, :order, :includes, :limit, :skip

Returns:

  • (Object)

    the content of the clause for this query.


360
361
362
363
# File 'lib/parse/query.rb', line 360

def clause(clause_name = :where)
  return unless [:keys, :where, :order, :includes, :limit, :skip].include?(clause_name)
  instance_variable_get "@#{clause_name}".to_sym
end

#clear(item = :results) ⇒ self

Clear a specific clause of this query. This can be one of: :where, :order, :includes, :skip, :limit, :count, :keys or :results.

Parameters:

  • item (:Symbol) (defaults to: :results)

    the clause to clear.

Returns:

  • (self)

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/parse/query.rb', line 246

def clear(item = :results)
  case item
  when :where
    # an array of Parse::Constraint subclasses
    @where = []
  when :order
    # an array of Parse::Order objects
    @order = []
  when :includes
    @includes = []
  when :skip
    @skip = 0
  when :limit
    @limit = nil
  when :count
    @count = 0
  when :keys
    @keys = []
  end
  @results = nil
  self # chaining
end

#compile(encode: true, includeClassName: false) ⇒ Hash

Complies the query and runs all prepare callbacks.

Parameters:

  • encode (Boolean)

    whether to encode the `where` clause to a JSON string.

  • includeClassName (Boolean)

    whether to include the class name of the collection.

Returns:

  • (Hash)

    a hash representing the prepared query request.

See Also:


822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
# File 'lib/parse/query.rb', line 822

def compile(encode: true, includeClassName: false)
  run_callbacks :prepare do
    q = {} #query
    q[:limit] = @limit if @limit.is_a?(Numeric) && @limit > 0
    q[:skip] = @skip if @skip > 0

    q[:include] = @includes.join(',') unless @includes.empty?
    q[:keys] = @keys.join(',')  unless @keys.empty?
    q[:order] = @order.join(',') unless @order.empty?
    unless @where.empty?
      q[:where] = Parse::Query.compile_where(@where)
      q[:where] = q[:where].to_json if encode
    end

    if @count && @count > 0
      # if count is requested
      q[:limit] = 0
      q[:count] = 1
    end
    if includeClassName
      q[:className] = @table
    end
    q
  end
end

#compile_whereHash

Returns a hash representing just the `where` clause of this query.

Returns:

  • (Hash)

    a hash representing just the `where` clause of this query.


849
850
851
# File 'lib/parse/query.rb', line 849

def compile_where
  self.class.compile_where( @where || [] )
end

#conditions(expressions = {}) ⇒ self Also known as: query, append

Add a set of query expressions and constraints.

Examples:

query.conditions({:field.gt => value})

Parameters:

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

    containing key value pairs of Parse::Operations and their value.

Returns:

  • (self)

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/parse/query.rb', line 310

def conditions(expressions = {})
  expressions.each do |expression, value|
    if expression == :order
      order value
    elsif expression == :keys
      keys value
    elsif expression == :key
      @key = value
    elsif expression == :skip
      skip value
    elsif expression == :limit
      limit value
    elsif expression == :include || expression == :includes
      includes(value)
    elsif expression == :cache
      self.cache = value
    elsif expression == :use_master_key
      self.use_master_key = value
    elsif expression == :session
      # you can pass a session token or a Parse::Session
      self.session_token = value
    else
      add_constraint(expression, value)
    end
  end # each
  self #chaining
end

#constraints(raw = false) ⇒ Array<Parse::Constraint>, Hash

Parameters:

  • raw (Boolean) (defaults to: false)

    whether to return the hash form of the constraints.

Returns:

  • (Array<Parse::Constraint>)

    if raw is false, an array of constraints composing the :where clause for this query.

  • (Hash)

    if raw i strue, an hash representing the constraints.


529
530
531
# File 'lib/parse/query.rb', line 529

def constraints(raw = false)
  raw ? where_constraints : @where
end

#countInteger

Perform a count query.

Examples:

# get number of songs with a play_count > 10
Song.count :play_count.gt => 10

# same
query = Parse::Query.new("Song")
query.where :play_count.gt => 10
query.count

Returns:

  • (Integer)

    the count result


620
621
622
623
624
625
626
# File 'lib/parse/query.rb', line 620

def count
  old_value = @count
  @count = 1
  res = client.find_objects(@table, compile.as_json, _opts ).count
  @count = old_value
  res
end

#decode(list) ⇒ Array<Parse::Object>

Builds objects based on the set of Parse JSON hashes in an array.

Parameters:

  • list (Array<Hash>)

    a list of Parse JSON hashes

Returns:


799
800
801
# File 'lib/parse/query.rb', line 799

def decode(list)
  list.map { |m| Parse::Object.build(m, @table) }.compact
end

#each { ... } ⇒ Array

Yields:

  • a block yield for each object in the result

Returns:

See Also:

  • Array#each

631
632
633
634
# File 'lib/parse/query.rb', line 631

def each
   return results.enum_for(:each) unless block_given? # Sparkling magic!
   results.each(&Proc.new)
end

#fetch!(compiled_query) ⇒ Parse::Response Also known as: execute!

Performs the fetch request for the query.

Parameters:

  • compiled_query (Hash)

    the compiled query

Returns:


734
735
736
737
738
739
740
741
# File 'lib/parse/query.rb', line 734

def fetch!(compiled_query)

  response = client.find_objects(@table, compiled_query.as_json, _opts )
  if response.error?
    puts "[ParseQuery] #{response.error}"
  end
  response
end

#first(limit = 1) ⇒ Parse::Object

Returns the first object from the result.

Parameters:

  • limit (Integer) (defaults to: 1)

    the number of first items to return.

Returns:


660
661
662
663
664
# File 'lib/parse/query.rb', line 660

def first(limit = 1)
  @results = nil if @limit != limit
  @limit = limit
  limit == 1 ? results.first : results.first(limit)
end

#includes(*fields) ⇒ self

Set a list of Parse Pointer columns to be fetched for matching records. You may chain multiple columns with the `.` operator.

Examples:

# assuming an 'Artist' has a pointer column for a 'Manager'
# and a Song has a pointer column for an 'Artist'.

# include the full artist object
Song.all(:includes => [:artist])

# Chaining - fetches the artist and the artist's manager for matching songs
Song.all :includes => ['artist.manager']

Parameters:

  • fields (Array)

    the list of Pointer columns to fetch.

Returns:

  • (self)

471
472
473
474
475
476
477
478
479
480
481
# File 'lib/parse/query.rb', line 471

def includes(*fields)
  @includes ||= []
  fields.flatten.each do |field|
    if field.nil? == false && field.respond_to?(:to_s)
      @includes.push Query.format_field(field).to_sym
    end
  end
  @includes.uniq!
  @results = nil if fields.count > 0
  self # chaining
end

#keys(*fields) ⇒ self

Note:

Use this feature with caution when working with the results, as values for the fields not specified in the query will be omitted in the resulting object.

Restrict the fields returned by the query. This is useful for larger query results set where some of the data will not be used, which reduces network traffic and deserialization performance.

Examples:

# results only contain :name field
Song.all :keys => :name

# multiple keys
Song.all :keys => [:name,:artist]

Parameters:

  • fields (Array)

    the name of the fields to return.

Returns:

  • (self)

379
380
381
382
383
384
385
386
387
388
389
# File 'lib/parse/query.rb', line 379

def keys(*fields)
  @keys ||= []
  fields.flatten.each do |field|
    if field.nil? == false && field.respond_to?(:to_s)
      @keys.push Query.format_field(field).to_sym
    end
  end
  @keys.uniq!
  @results = nil if fields.count > 0
  self # chaining
end

#limit(count) ⇒ self

Limit the number of objects returned by the query. The default is 100, with Parse allowing a maximum of 1000. The framework also allows a value of `:max`. Utilizing this will have the framework continually intelligently utilize `:skip` to continue to paginate through results until no more results match the query criteria. When utilizing `all()`, `:max` is the default option for `:limit`.

Examples:

Song.all :limit => 1 # same as Song.first
Song.all :limit => 2025 # large limits supported.
Song.all :limit => :max # as many records as possible.

Parameters:

  • count (Integer, Symbol)

    The number of records to return. You may pass :max to get as many as 11_000 records with the aid if skipping.

Returns:

  • (self)

439
440
441
442
443
444
445
446
447
448
449
450
# File 'lib/parse/query.rb', line 439

def limit(count)
  if count.is_a?(Numeric)
    @limit = [ 0, count.to_i ].max
  elsif count == :max
    @limit = :max
  else
    @limit = nil
  end

  @results = nil
  self #chaining
end

#map { ... } ⇒ Array

Yields:

  • a block yield for each object in the result

Returns:

See Also:

  • Array#map

639
640
641
642
# File 'lib/parse/query.rb', line 639

def map
  return results.enum_for(:map) unless block_given? # Sparkling magic!
  results.map(&Proc.new)
end

#or_where(where_clauses = []) ⇒ Query

Combine two where clauses into an OR constraint. Equivalent to the `$or` Parse query operation. This is useful if you want to find objects that match several queries. We overload the `|` operator in order to have a clean syntax for joining these `or` operations.

Examples:

query = Player.where(:wins.gt => 150)
query.or_where(:wins.lt => 5)
# where wins > 150 || wins < 5
results = query.results

# or_query = query1 | query2 | query3 ...
# ex. where wins > 150 || wins < 5
query = Player.where(:wins.gt => 150) | Player.where(:wins.lt => 5)
results = query.results

Parameters:

  • where_clauses (Array<Parse::Constraint>) (defaults to: [])

    a list of Parse::Constraint objects to combine.

Returns:

  • (Query)

    the combined query with an OR clause.


580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
# File 'lib/parse/query.rb', line 580

def or_where(where_clauses = [])
  where_clauses = where_clauses.where if where_clauses.is_a?(Parse::Query)
  where_clauses = Parse::Query.new(@table, where_clauses ).where if where_clauses.is_a?(Hash)
  return self if where_clauses.blank?
  # we can only have one compound query constraint. If we need to add another OR clause
  # let's find the one we have (if any)
  compound = @where.find { |f| f.is_a?(Parse::Constraint::CompoundQueryConstraint) }
  # create a set of clauses that are not an OR clause.
  remaining_clauses = @where.select { |f| f.is_a?(Parse::Constraint::CompoundQueryConstraint) == false }
  # if we don't have a OR clause to reuse, then create a new one with then
  # current set of constraints
  if compound.blank?
    compound = Parse::Constraint::CompoundQueryConstraint.new :Parse::Query.compile_where(remaining_clauses) ]
  end
  # then take the where clauses from the second query and append them.
  compound.value.push Parse::Query.compile_where(where_clauses)
  #compound = Parse::Constraint::CompoundQueryConstraint.new :or, [remaining_clauses, or_where_query.where]
  @where = [compound]
  self #chaining
end

#order(*ordering) ⇒ self

Add a sorting order for the query.

Examples:

# order updated_at ascending order
Song.all :order => :updated_at

# first order by highest like_count, then by ascending name.
# Note that ascending is the default if not specified (ex. `:name.asc`)
Song.all :order => [:like_count.desc, :name]

Parameters:

Returns:

  • (self)

401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/parse/query.rb', line 401

def order(*ordering)
  @order ||= []
  ordering.flatten.each do |order|
    order = Order.new(order) if order.respond_to?(:to_sym)
    if order.is_a?(Order)
      order.field = Query.format_field(order.field)
      @order.push order
    end
  end #value.each
  @results = nil if ordering.count > 0
  self #chaining
end

#prepared(includeClassName: false) ⇒ Hash

Returns a compiled query without encoding the where clause.

Parameters:

  • includeClassName (Boolean)

    whether to include the class name of the collection in the resulting compiled query.

Returns:

  • (Hash)

    a hash representing the prepared query request.


812
813
814
# File 'lib/parse/query.rb', line 812

def prepared(includeClassName: false)
  compile(encode: false, includeClassName: includeClassName)
end

#prettyString

Retruns a formatted JSON string representing the query, useful for debugging.

Returns:


855
856
857
# File 'lib/parse/query.rb', line 855

def pretty
  JSON.pretty_generate( as_json )
end

Raises:

  • (ArgumentError)

452
453
454
455
456
# File 'lib/parse/query.rb', line 452

def related_to(field, pointer)
  raise ArgumentError, "Object value must be a Parse::Pointer type" unless pointer.is_a?(Parse::Pointer)
  add_constraint field.to_sym.related_to, pointer
  self #chaining
end

#results(raw: false) { ... } ⇒ Array<Hash>, Array<Parse::Object> Also known as: result

Executes the query and builds the result set of Parse::Objects that matched. When this method is passed a block, the block is yielded for each matching item in the result, and the items are not returned. This methodology is more performant as large quantifies of objects are fetched in batches and all of them do not have to be kept in memory after the query finishes executing. This is the recommended method of processing large result sets.

Examples:

query = Parse::Query.new("_User", :created_at.before => DateTime.now)
users = query.results # => Array of Parse::User objects.

query = Parse::Query.new("_User", limit: :max)

query.results do |user|
 # recommended; more memory efficient
end

Parameters:

  • raw (Boolean)

    whether to get the raw hash results of the query instead of a set of Parse::Object subclasses.

Yields:

  • a block to iterate for each object that matched the query.

Returns:

  • (Array<Hash>)

    if raw is set to true, a set of Parse JSON hashes.

  • (Array<Parse::Object>)

    if raw is set to false, a list of matching Parse::Object subclasses.


765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/parse/query.rb', line 765

def results(raw: false)
  if @results.nil?
    if block_given?
      max_results(raw: raw, &Proc.new)
    elsif @limit.is_a?(Numeric)
      response = fetch!( compile )
      return [] if response.error?
      items = raw ? response.results : decode(response.results)
      return items.each(&Proc.new) if block_given?
      @results = items
    else
      @results = max_results(raw: raw)
    end
  end
  @results
end

#select { ... } ⇒ Array

Yields:

  • a block yield for each object in the result

Returns:

See Also:

  • Array#select

647
648
649
650
# File 'lib/parse/query.rb', line 647

def select
  return results.enum_for(:select) unless block_given? # Sparkling magic!
  results.select(&Proc.new)
end

#skip(amount) ⇒ self

Use with limit to paginate through results. Default is 0.

Examples:

# get the next 3 songs after the first 10
Song.all :limit => 3, :skip => 10

Parameters:

  • amount (Integer)

    The number of records to skip.

Returns:

  • (self)

420
421
422
423
424
# File 'lib/parse/query.rb', line 420

def skip(amount)
  @skip = [0,amount.to_i].max
  @results = nil
  self #chaining
end

#to_aArray

Returns:

See Also:

  • Array#to_a

654
655
656
# File 'lib/parse/query.rb', line 654

def to_a
  results.to_a
end

#where(conditions = nil, opts = {}) ⇒ self

Add additional query constraints to the `where` clause. The `where` clause is based on utilizing a set of constraints on the defined column names in your Parse classes. The constraints are implemented as method operators on field names that are tied to a value. Any symbol/string that is not one of the main expression keywords described here will be considered as a type of query constraint for the `where` clause in the query.

Examples:

# parts of a single where constraint
{ :column.constraint => value }

Parameters:

  • conditions (Hash) (defaults to: nil)

    a set of constraints for this query.

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

    a set of options when adding the constraints. This is specific for each Parse::Constraint.

Returns:

  • (self)

See Also:


554
555
556
557
558
559
560
561
562
# File 'lib/parse/query.rb', line 554

def where(conditions = nil, opts = {})
  return @where if conditions.nil?
  if conditions.is_a?(Hash)
    conditions.each do |operator, value|
      add_constraint(operator, value, opts)
    end
  end
  self #chaining
end

#where_constraintsHash

Formats the current set of Parse::Constraint instances in the where clause as an expression hash.

Returns:

  • (Hash)

    the set of constraints


536
537
538
# File 'lib/parse/query.rb', line 536

def where_constraints
  @where.reduce({}) { |memo, constraint| memo[constraint.operation] = constraint.value; memo }
end

#|(other_query) ⇒ Query

Returns the combined query with an OR clause.

Returns:

  • (Query)

    the combined query with an OR clause.

Raises:

  • (ArgumentError)

See Also:


603
604
605
606
607
608
# File 'lib/parse/query.rb', line 603

def |(other_query)
    raise ArgumentError, "Parse queries must be of the same class #{@table}." unless @table == other_query.table
    copy_query = self.clone
    copy_query.or_where other_query.where
    copy_query
end