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)


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

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)

# same, but ignore field formatting
query.add_constraint(:like_count.gt, 20, filter: false)

Parameters:

  • operator (Parse::Operator)

    an operator object containing the operation and operand.

  • value (Object) (defaults to: nil)

    the value for the constraint.

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

    A set of options. Passing :filter with false, will skip field formatting.

Returns:

  • (self)

See Also:



508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
# File 'lib/parse/query.rb', line 508

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:



839
840
841
# File 'lib/parse/query.rb', line 839

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)


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

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) (defaults to: true)

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

  • includeClassName (Boolean) (defaults to: false)

    whether to include the class name of the collection.

Returns:

  • (Hash)

    a hash representing the prepared query request.

See Also:



857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
# File 'lib/parse/query.rb', line 857

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.



884
885
886
# File 'lib/parse/query.rb', line 884

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)


309
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
# File 'lib/parse/query.rb', line 309

def conditions(expressions = {})
  expressions.each do |expression, value|
    if expression == :order
      order value
    elsif expression == :keys
      keys value
    elsif expression == :key
      keys [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.



534
535
536
# File 'lib/parse/query.rb', line 534

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



654
655
656
657
658
659
660
# File 'lib/parse/query.rb', line 654

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:



834
835
836
# File 'lib/parse/query.rb', line 834

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

#distinct(field) ⇒ Object

Note:

This feature requires use of the Master Key in the API.

Queries can be made using distinct, allowing you find unique values for a specified field. For this to be performant, please remember to index your database.

Examples:

# Return a set of unique city names
# for users who are greater than 21 years old
Parse::Query.all(distinct: :age)
query = Parse::Query.new("_User")
query.where :age.gt => 21
# triggers query
query.distinct(:city) #=> ["San Diego", "Los Angeles", "San Juan"]

Parameters:

  • field (Symbol|String)

    The name of the field used for filtering.

Version:

  • 1.8.0



628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
# File 'lib/parse/query.rb', line 628

def distinct(field)
  if field.nil? == false && field.respond_to?(:to_s)
    # disable counting if it was enabled.
    old_count_value = @count
    @count = nil
    compile_query = compile # temporary store
    # add distinct field
    compile_query[:distinct] = Query.format_field(field).to_sym
    @count = old_count_value
    # perform aggregation
    return client.aggregate_objects(@table, compile_query.as_json, _opts).result
  else
    raise ArgumentError, "Invalid field name passed to `distinct`."
  end
end

#each { ... } ⇒ Array

Yields:

  • a block yield for each object in the result

Returns:

See Also:

  • Array#each


665
666
667
668
# File 'lib/parse/query.rb', line 665

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:



768
769
770
771
772
773
774
# File 'lib/parse/query.rb', line 768

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:



694
695
696
697
698
# File 'lib/parse/query.rb', line 694

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 records as possible (Parse-Server dependent).

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


673
674
675
676
# File 'lib/parse/query.rb', line 673

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.



585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
# File 'lib/parse/query.rb', line 585

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 :or, [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) (defaults to: false)

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

Returns:

  • (Hash)

    a hash representing the prepared query request.



847
848
849
# File 'lib/parse/query.rb', line 847

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

#prettyString

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

Returns:



890
891
892
# File 'lib/parse/query.rb', line 890

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) (defaults to: false)

    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.



799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
# File 'lib/parse/query.rb', line 799

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


681
682
683
684
# File 'lib/parse/query.rb', line 681

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


688
689
690
# File 'lib/parse/query.rb', line 688

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:



559
560
561
562
563
564
565
566
567
# File 'lib/parse/query.rb', line 559

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



541
542
543
# File 'lib/parse/query.rb', line 541

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:



608
609
610
611
612
613
# File 'lib/parse/query.rb', line 608

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