parse-stack 1.3.1 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -1
- data/Changes.md +25 -1
- data/Gemfile +10 -0
- data/Gemfile.lock +10 -9
- data/README.md +593 -254
- data/Rakefile +1 -0
- data/bin/console +5 -0
- data/lib/parse-stack.rb +2 -0
- data/lib/parse/api/batch.rb +2 -1
- data/lib/parse/api/files.rb +2 -0
- data/lib/parse/api/objects.rb +2 -0
- data/lib/parse/client.rb +31 -2
- data/lib/parse/client/authentication.rb +10 -0
- data/lib/parse/client/body_builder.rb +3 -0
- data/lib/parse/client/request.rb +1 -1
- data/lib/parse/client/response.rb +1 -0
- data/lib/parse/model/associations/pointer_collection_proxy.rb +2 -2
- data/lib/parse/model/associations/relation_collection_proxy.rb +1 -0
- data/lib/parse/model/core/actions.rb +8 -8
- data/lib/parse/model/core/properties.rb +9 -0
- data/lib/parse/model/core/schema.rb +9 -0
- data/lib/parse/model/date.rb +4 -0
- data/lib/parse/model/file.rb +17 -2
- data/lib/parse/model/geopoint.rb +39 -2
- data/lib/parse/model/object.rb +2 -1
- data/lib/parse/model/pointer.rb +3 -0
- data/lib/parse/model/push.rb +2 -2
- data/lib/parse/query.rb +33 -17
- data/lib/parse/query/constraint.rb +2 -2
- data/lib/parse/query/constraints.rb +62 -6
- data/lib/parse/query/operation.rb +1 -0
- data/lib/parse/stack.rb +1 -0
- data/lib/parse/stack/tasks.rb +107 -0
- data/lib/parse/stack/version.rb +1 -1
- data/lib/parse/webhooks.rb +2 -2
- data/lib/parse/webhooks/payload.rb +2 -0
- data/lib/parse/webhooks/registration.rb +15 -10
- data/parse-stack.gemspec +8 -15
- metadata +20 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36eda4b2e4b7cfabe79550eb3c33345f6d9fdaaf
|
4
|
+
data.tar.gz: efdef75bc9457d307563f5e0e254733cb2c638fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc156d8689d64921540fb44c3fc41446c4bfc67ea869d6f6c73e28a32ae0398089bdd2b7691c9df0ccce6cfcc893abbf872090439906580edc7c3bd9e1568075
|
7
|
+
data.tar.gz: b07ef6631868a733b0967fcf0e3cad592f46e179d451e61d1ea3826130f0f00a9e85861796d1a49d2db0bbe160fb1e680a6884e7c46749f5026beb9d9b8090bc
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Changes.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# Parse-Stack Changes
|
2
2
|
|
3
|
+
1.3.7
|
4
|
+
-----------
|
5
|
+
- Fixes json_api loading issue between ruby json and active_model_serializers.
|
6
|
+
- Fixes loading active_support core extensions.
|
7
|
+
|
8
|
+
1.3.5
|
9
|
+
-----------
|
10
|
+
- Support for passing a `:session_token` as part of a Parse::Query.
|
11
|
+
- Default mime-type for Parse::File instances is `image/jpeg`. You can override the default by setting
|
12
|
+
`Parse::File.default_mime_type`.
|
13
|
+
- Added `Parse.config` for easy access to `Parse::Client.session(:default).config`
|
14
|
+
- Support for `Parse.auto_upgrade!` to easily upgrade all schemas.
|
15
|
+
- You can import useful rake tasks by requiring `parse/stack/tasks` in your rake file.
|
16
|
+
- Changes the format in `select` and `reject` queries (see documentation).
|
17
|
+
- Latitude and longitude values are now validated with warnings. Will raise exceptions in the future.
|
18
|
+
- Additional alias methods for queries.
|
19
|
+
- Added `$within` => `$box` GeoPoint query. (see documentation)
|
20
|
+
- Improves support when using Parse-Server.
|
21
|
+
- Major documentation updates.
|
22
|
+
- `limit` no longer defaults to 100 in `Parse::Query`. This will allow Parse-Server to determine default limit, if any. (1.3.4)
|
23
|
+
- `:bool` property type has been added as an alias to `:boolean`. (1.3.5)
|
24
|
+
- You can turn off formatting field names with `Parse::Query.field_formatter = nil`. (1.3.5)
|
25
|
+
|
26
|
+
|
3
27
|
1.3.1
|
4
28
|
-----------
|
5
29
|
- Parse::Query now supports `:cache` and `:use_master_key` option. (experimental)
|
@@ -47,7 +71,7 @@ login with Android devices.
|
|
47
71
|
-----------
|
48
72
|
- In Query `join` has been renamed to `matches`.
|
49
73
|
- Not In Query `exclude` has been renamed to `excludes` for consistency.
|
50
|
-
- Parse::Query now has a `:
|
74
|
+
- Parse::Query now has a `:keys` operation to be usd when passing sub-queries to `select` and `matches`
|
51
75
|
- Improves query supporting `select`, `matches`, `matches` and `excludes`.
|
52
76
|
- Regular expression queries for `like` now send regex options
|
53
77
|
|
data/Gemfile
CHANGED
@@ -2,4 +2,14 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in parse-stack.gemspec
|
4
4
|
gemspec
|
5
|
+
|
5
6
|
gem 'dotenv'
|
7
|
+
gem 'rake'
|
8
|
+
|
9
|
+
group :test, :development do
|
10
|
+
gem 'byebug'
|
11
|
+
gem 'minitest'
|
12
|
+
gem 'pry'
|
13
|
+
gem 'pry-stack_explorer'
|
14
|
+
gem 'pry-nav'
|
15
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
parse-stack (1.3.
|
4
|
+
parse-stack (1.3.7)
|
5
5
|
active_model_serializers (>= 0.9, < 1)
|
6
6
|
activemodel (>= 4.2.1, < 6)
|
7
7
|
activesupport (>= 4.2.1, < 6)
|
@@ -42,6 +42,7 @@ GEM
|
|
42
42
|
binding_of_caller (0.7.2)
|
43
43
|
debug_inspector (>= 0.0.1)
|
44
44
|
builder (3.2.2)
|
45
|
+
byebug (9.0.5)
|
45
46
|
coderay (1.1.1)
|
46
47
|
concurrent-ruby (1.0.2)
|
47
48
|
debug_inspector (0.0.2)
|
@@ -67,7 +68,7 @@ GEM
|
|
67
68
|
pkg-config (~> 1.1.7)
|
68
69
|
parallel (1.9.0)
|
69
70
|
pkg-config (1.1.7)
|
70
|
-
pry (0.10.
|
71
|
+
pry (0.10.4)
|
71
72
|
coderay (~> 1.1.0)
|
72
73
|
method_source (~> 0.8.1)
|
73
74
|
slop (~> 3.4)
|
@@ -90,7 +91,7 @@ GEM
|
|
90
91
|
method_source
|
91
92
|
rake (>= 0.8.7)
|
92
93
|
thor (>= 0.18.1, < 2.0)
|
93
|
-
rake (
|
94
|
+
rake (11.2.2)
|
94
95
|
slop (3.6.0)
|
95
96
|
thor (0.19.1)
|
96
97
|
thread_safe (0.3.5)
|
@@ -101,14 +102,14 @@ PLATFORMS
|
|
101
102
|
ruby
|
102
103
|
|
103
104
|
DEPENDENCIES
|
104
|
-
|
105
|
+
byebug
|
105
106
|
dotenv
|
106
|
-
minitest
|
107
|
+
minitest
|
107
108
|
parse-stack!
|
108
|
-
pry
|
109
|
-
pry-nav
|
110
|
-
pry-stack_explorer
|
111
|
-
rake
|
109
|
+
pry
|
110
|
+
pry-nav
|
111
|
+
pry-stack_explorer
|
112
|
+
rake
|
112
113
|
|
113
114
|
BUNDLED WITH
|
114
115
|
1.12.5
|
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
# Parse
|
2
|
-
Parse
|
1
|
+
# Parse-Stack - A Parse-Server Ruby Client and ORM
|
2
|
+
Parse Stack is an opinionated framework for ruby applications that utilize the [Parse Server Platform](https://github.com/ParsePlatform/parse-server). It provides a client adapter, a query engine, an object relational mapper (ORM) and a Cloud Code Webhooks rack application.
|
3
|
+
|
4
|
+
### Code Status
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/parse-stack.svg)](https://badge.fury.io/rb/parse-stack)
|
6
|
+
[![Build Status](https://travis-ci.org/modernistik/parse-stack.svg?branch=master)](https://travis-ci.org/modernistik/parse-stack)
|
3
7
|
|
4
8
|
## Table Of Contents
|
5
9
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
@@ -9,67 +13,81 @@ Parse::Stack is an opinionated framework for larger scale ruby applications that
|
|
9
13
|
- [Overview](#overview)
|
10
14
|
- [Main Features](#main-features)
|
11
15
|
- [Architecture](#architecture)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
- [
|
17
|
-
- [
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
- [
|
24
|
-
- [
|
25
|
-
|
16
|
+
- [Parse::Client](#parseclient)
|
17
|
+
- [Parse::Query](#parsequery)
|
18
|
+
- [Parse::Object](#parseobject)
|
19
|
+
- [Parse::Webhooks](#parsewebhooks)
|
20
|
+
- [Connection Setup](#connection-setup)
|
21
|
+
- [Connection Options](#connection-options)
|
22
|
+
- [Core Classes](#core-classes)
|
23
|
+
- [Parse::Pointer](#parsepointer)
|
24
|
+
- [Parse::File](#parsefile)
|
25
|
+
- [Parse::Date](#parsedate)
|
26
|
+
- [Parse::GeoPoint](#parsegeopoint)
|
27
|
+
- [Calculating Distances between locations](#calculating-distances-between-locations)
|
28
|
+
- [Parse::Bytes](#parsebytes)
|
29
|
+
- [Modeling and Subclassing](#modeling-and-subclassing)
|
30
|
+
- [Defining Properties](#defining-properties)
|
31
|
+
- [Accessor Aliasing](#accessor-aliasing)
|
26
32
|
- [Property Options](#property-options)
|
27
|
-
- [`:required => (true|false)`](#required--truefalse)
|
28
|
-
- [`:field => (string)`](#field--string)
|
29
|
-
- [`:default => (value|proc)`](#default--valueproc)
|
30
|
-
- [`:alias => (true|false)`](#alias--truefalse)
|
31
|
-
- [`:symbolize => (true|false)`](#symbolize--truefalse)
|
32
|
-
- [Overriding Property Accessors](#overriding-property-accessors)
|
33
33
|
- [Associations](#associations)
|
34
34
|
- [Belongs To](#belongs-to)
|
35
|
-
- [Options](#options)
|
36
|
-
- [`:required => (true|false)`](#required--truefalse-1)
|
37
|
-
- [`:as => (string)`](#as--string)
|
38
|
-
- [`:field => (string)`](#field--string-1)
|
39
35
|
- [Has Many (Array or Relation)](#has-many-array-or-relation)
|
40
|
-
|
41
|
-
|
42
|
-
- [
|
43
|
-
- [Examples](#examples)
|
36
|
+
- [Creating, Saving and Deleting Records](#creating-saving-and-deleting-records)
|
37
|
+
- [Create](#create)
|
38
|
+
- [Saving](#saving)
|
44
39
|
- [Raising an exception when save fails](#raising-an-exception-when-save-fails)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
- [Destroy](#destroy)
|
40
|
+
- [Modifying Associations](#modifying-associations)
|
41
|
+
- [Batch Save Requests](#batch-save-requests)
|
42
|
+
- [Magic `save_all`](#magic-save_all)
|
43
|
+
- [Deleting](#deleting)
|
50
44
|
- [Fetching, Finding and Counting Records](#fetching-finding-and-counting-records)
|
51
45
|
- [Auto-Fetching Associations](#auto-fetching-associations)
|
52
46
|
- [Advanced Querying](#advanced-querying)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
47
|
+
- [Results Caching](#results-caching)
|
48
|
+
- [Counting](#counting)
|
49
|
+
- [Query Expressions](#query-expressions)
|
50
|
+
- [:order](#order)
|
51
|
+
- [:keys](#keys)
|
52
|
+
- [:includes](#includes)
|
53
|
+
- [:limit](#limit)
|
54
|
+
- [:skip](#skip)
|
55
|
+
- [:cache](#cache)
|
56
|
+
- [:use_master_key](#use_master_key)
|
57
|
+
- [:session_token](#session_token)
|
58
|
+
- [:where](#where)
|
59
|
+
- [Query Constraints](#query-constraints)
|
60
|
+
- [Equals](#equals)
|
61
|
+
- [Less Than](#less-than)
|
62
|
+
- [Less Than or Equal To](#less-than-or-equal-to)
|
63
|
+
- [Greater Than](#greater-than)
|
64
|
+
- [Greater Than or Equal](#greater-than-or-equal)
|
65
|
+
- [Not Equal To](#not-equal-to)
|
66
|
+
- [Nullability Check](#nullability-check)
|
67
|
+
- [Exists](#exists)
|
68
|
+
- [Contained In](#contained-in)
|
69
|
+
- [Not Contained In](#not-contained-in)
|
70
|
+
- [Contains All](#contains-all)
|
71
|
+
- [Regex Matching](#regex-matching)
|
72
|
+
- [Select](#select)
|
73
|
+
- [Reject](#reject)
|
74
|
+
- [Matches Query](#matches-query)
|
75
|
+
- [Excludes Query](#excludes-query)
|
76
|
+
- [Geo Queries](#geo-queries)
|
77
|
+
- [Max Distance Constraint](#max-distance-constraint)
|
78
|
+
- [Bounding Box Constraint](#bounding-box-constraint)
|
79
|
+
- [Relational Queries](#relational-queries)
|
80
|
+
- [Compound Queries](#compound-queries)
|
81
|
+
- [Cloud Code Functions](#cloud-code-functions)
|
82
|
+
- [Cloud Code Background Jobs](#cloud-code-background-jobs)
|
64
83
|
- [Hooks and Callbacks](#hooks-and-callbacks)
|
84
|
+
- [Schema Upgrades and Migrations](#schema-upgrades-and-migrations)
|
65
85
|
- [Push Notifications](#push-notifications)
|
66
|
-
- [Webhooks](#webhooks)
|
67
|
-
- [
|
68
|
-
- [
|
86
|
+
- [Cloud Code Webhooks](#cloud-code-webhooks)
|
87
|
+
- [Cloud Code functions](#cloud-code-functions)
|
88
|
+
- [Cloud Code Triggers](#cloud-code-triggers)
|
69
89
|
- [Mounting Webhooks Application](#mounting-webhooks-application)
|
70
90
|
- [Register Webhooks](#register-webhooks)
|
71
|
-
- [Cloud Code Functions](#cloud-code-functions)
|
72
|
-
- [Cloud Code Background Jobs](#cloud-code-background-jobs)
|
73
91
|
- [Parse REST API Client](#parse-rest-api-client)
|
74
92
|
- [Options](#options-2)
|
75
93
|
- [Request Caching](#request-caching)
|
@@ -85,8 +103,9 @@ Parse::Stack is a full stack framework that utilizes several ideas behind [DataM
|
|
85
103
|
|
86
104
|
require 'parse/stack'
|
87
105
|
|
88
|
-
Parse.setup
|
89
|
-
|
106
|
+
Parse.setup app_id: APP_ID,
|
107
|
+
api_key: REST_API_KEY,
|
108
|
+
server_url: 'https://api.parse.com/1/'
|
90
109
|
|
91
110
|
# Object Mapper
|
92
111
|
class Song < Parse::Object
|
@@ -132,51 +151,113 @@ While there are many additional features of the framework, these are the main po
|
|
132
151
|
|
133
152
|
- Object Relational Mapping with dirty tracking.
|
134
153
|
- Easy management of Parse GeoPoints, Files and ACLs.
|
135
|
-
- Queries support with caching middleware. (Reduces API usage)
|
154
|
+
- Parse Queries support with caching middleware. (Reduces API usage)
|
136
155
|
- Support for all Parse data types.
|
137
156
|
- One-to-One, One-to-Many and Many-to-Many relations.
|
138
157
|
- Integration with Parse Cloud Code Webhooks.
|
139
158
|
- Send Push notifications with advanced targeting.
|
140
159
|
- Schema upgrades and migrations.
|
160
|
+
- Rake tasks for webhook registrations.
|
161
|
+
- Some special magic with :save_all and :max limit fetch.
|
141
162
|
|
142
163
|
## Architecture
|
143
164
|
The architecture of `Parse::Stack` is broken into four main components.
|
144
165
|
|
145
|
-
|
166
|
+
### Parse::Client
|
146
167
|
This class is the core and low level API for the Parse SDK REST interface that is used by the other components. It can manage multiple sessions, which means you can have multiple client instances pointing to different Parse Applications at the same time. It handles sending raw requests as well as providing Request/Response objects for all API handlers. The connection engine is Faraday, which means it is open to add any additional middleware for features you'd like to implement.
|
147
168
|
|
148
|
-
|
169
|
+
### Parse::Query
|
149
170
|
This class implements the [Parse REST Querying](https://parse.com/docs/rest/guide#queries) interface in the [DataMapper finder syntax style](http://datamapper.org/docs/find.html). It compiles a set of query constraints and utilizes `Parse::Client` to send the request and provide the raw results. This class can be used without the need to define models.
|
150
171
|
|
151
|
-
|
172
|
+
### Parse::Object
|
152
173
|
This component is main class for all object relational mapping subclasses for your application. It provides features in order to map your remote Parse records to a local ruby object. It implements the Active::Model interface to provide a lot of additional features, CRUD operations, querying, including dirty tracking, JSON serialization, save/destroy callbacks and others. While we are overlooking some functionality, for simplicity, you will mainly be working with Parse::Object as your superclass. While not required, it is highly recommended that you define a model (Parse::Object subclass) for all the Parse classes in your application.
|
153
174
|
|
154
|
-
|
155
|
-
Parse provides a feature called [Cloud Code Webhooks](http://blog.parse.com/announcements/introducing-cloud-code-webhooks/). For most applications, save/delete triggers and cloud functions tend to be implemented by Parse's own hosted Javascript solution called Cloud Code. However, Parse provides the ability to have these hooks utilize your hosted solution instead of their own, since their environment is limited in terms of resources and tools.
|
175
|
+
### Parse::Webhooks
|
176
|
+
Parse provides a feature called [Cloud Code Webhooks](http://blog.parse.com/announcements/introducing-cloud-code-webhooks/). For most applications, save/delete triggers and cloud functions tend to be implemented by Parse's own hosted Javascript solution called Cloud Code. However, Parse provides the ability to have these hooks utilize your hosted solution instead of their own, since their environment is limited in terms of resources and tools. If you are using the open source [Parse Server](https://github.com/ParsePlatform/parse-server), you must enable this hooks feature by enabling the environment variable `PARSE_EXPERIMENTAL_HOOKS_ENABLED` on your Parse server.
|
156
177
|
|
157
|
-
##
|
158
|
-
|
178
|
+
## Field Naming Conventions
|
179
|
+
By convention in Ruby (see [Style Guide](https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars)), symbols and variables are expressed in lower_snake_case form. Parse, however, prefers column names in **lower-first camel case** (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. As an additional exception to this rule, the field key of `id` will automatically be converted to the `objectId` field when used. If you do not want this to happen, you can turn off or change the value `Parse::Query.field_formatter` as shown below. Though we recommend leaving the default `:columnize` if possible.
|
159
180
|
|
160
|
-
|
181
|
+
```ruby
|
182
|
+
# default uses :columnize
|
183
|
+
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
|
184
|
+
query.compile_where # {"fieldOne"=>1, "fieldTwo"=>2, "fieldThree"=>3}
|
161
185
|
|
162
|
-
|
163
|
-
|
186
|
+
# turn off
|
187
|
+
Parse::Query.field_formatter = nil
|
188
|
+
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
|
189
|
+
query.compile_where # {"field_one"=>1, "FieldTwo"=>2, "Field_Three"=>3}
|
190
|
+
|
191
|
+
# force everything camel case
|
192
|
+
Parse::Query.field_formatter = :camelize
|
193
|
+
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
|
194
|
+
query.compile_where # {"FieldOne"=>1, "FieldTwo"=>2, "FieldThree"=>3}
|
195
|
+
|
196
|
+
```
|
197
|
+
|
198
|
+
|
199
|
+
## Connection Setup
|
200
|
+
To connect to a Parse server, you will need a minimum of an `application_id`, an `api_key` and a `server_url`. To connect to the server endpoint, you use the `Parse.setup()` method below.
|
164
201
|
|
165
202
|
```ruby
|
166
|
-
|
167
|
-
|
168
|
-
|
203
|
+
Parse.setup app_id: "YOUR_APP_ID",
|
204
|
+
api_key: "YOUR_API_KEY",
|
205
|
+
server_url: 'https://api.parse.com/1/' #default
|
206
|
+
```
|
169
207
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
208
|
+
If you wish to add additional connection middleware to the stack, you may do so by utilizing passing a block to the setup method.
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
Parse.setup( ... ) do |conn|
|
212
|
+
# conn is a Faraday connection object
|
213
|
+
conn.use Your::Middleware
|
214
|
+
conn.response :logger
|
215
|
+
# ....
|
216
|
+
end
|
217
|
+
```
|
218
|
+
|
219
|
+
Calling `setup` will create the default `Parse::Client` session object that will be used for all models and requests in the stack. You may retrive this client by calling the class `session()` method. It is possible to create different client connections and have different models point to different Parse applications and endpoints at the same time.
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
default_client = Parse::Client.session(:default)
|
223
|
+
# or just Parse::Client.session
|
174
224
|
```
|
175
225
|
|
176
|
-
###
|
226
|
+
### Connection Options
|
227
|
+
There are additional connection options that you may pass the setup method when creating a `Parse::Client`.
|
228
|
+
|
229
|
+
#### `:server_url`
|
230
|
+
The server url of your Parse-Server if you are not using the hosted Parse.com service. By default it will use `PARSE_SERVER_URL` environment variable available or fall back to `https://api.parse.com/1/` if not specified.
|
231
|
+
|
232
|
+
#### `:app_id`
|
233
|
+
The Parse application id. By default it will use `PARSE_APP_ID` environment variable if not specified.
|
234
|
+
|
235
|
+
#### `:api_key`
|
236
|
+
The Parse REST API Key. By default it will use `PARSE_API_KEY` environment variable if not specified.
|
237
|
+
|
238
|
+
#### `:master_key` _(optional)_
|
239
|
+
The Parse application master key. If this key is set, it will be sent on every request sent by the client and your models. By default it will use `PARSE_MASTER_KEY` environment variable if not specified.
|
240
|
+
|
241
|
+
#### `:logging`
|
242
|
+
A true or false value. It provides you additional logging information of requests and responses. If set to the special symbol of `:debug`, it will provide additional payload data in the log messages.
|
243
|
+
|
244
|
+
#### `:adapter`
|
245
|
+
The connection adapter. By default it uses the `Faraday.default_adapter` which is Net/HTTP.
|
246
|
+
|
247
|
+
#### `:cache`
|
248
|
+
A caching adapter of type `Moneta::Transformer`. Caching queries and object fetches can help improve the performance of your application, even if it is for a few seconds. Only successful `GET` object fetches and queries (non-empty) will be cached. You may set the default expiration time with the `expires` option. See related: [Moneta](https://github.com/minad/moneta). At any point in time you may clear the cache by calling the `clear_cache!` method on the client connection.
|
249
|
+
|
250
|
+
#### `:expires`
|
251
|
+
Sets the default cache expiration time (in seconds) for successful non-empty `GET` requests when using the caching middleware. The default value is 3 seconds. If `:expires` is set to 0, caching will be disabled. You can always clear the current state of the cache using the `clear_cache!` method on your `Parse::Client` instance.
|
252
|
+
|
253
|
+
#### `:faraday`
|
254
|
+
You may pass a hash of options that will be passed to the `Faraday` constructor.
|
255
|
+
|
256
|
+
|
257
|
+
## Core Classes
|
177
258
|
While some native data types are similar to the ones supported by Ruby natively, other ones are more complex and require their dedicated classes.
|
178
259
|
|
179
|
-
|
260
|
+
### Parse::Pointer
|
180
261
|
An important concept is the `Parse::Pointer` class. This is the superclass of `Parse::Object` and represents the pointer type in Parse. A `Parse::Pointer` only contains data about the specific Parse class and the `id` for the object. Therefore, creating an instance of any Parse::Object subclass with only the `:id` field set will be considered in "pointer" state even though its specific class is not `Parse::Pointer` type. The only case that you may have a Parse::Pointer is in the case where an object was received for one of your classes and the framework has no registered class handler for it. Using the example above, assume you have the tables `Post`, `Comment` and `Author` defined in your remote Parse application, but have only defined `Post` and `Commentary` locally.
|
181
262
|
|
182
263
|
```ruby
|
@@ -204,7 +285,7 @@ comment.author # <Parse::Pointer @parse_class="Author", @id="hZLbW6ofKC">
|
|
204
285
|
|
205
286
|
The effect is that for any unknown classes that the framework encounters, it will generate Parse::Pointer instances until you define those classes with valid properties and associations. While this might be ok for some classes you do not use, we still recommend defining all your Parse classes locally in the framework.
|
206
287
|
|
207
|
-
|
288
|
+
### Parse::File
|
208
289
|
This class represents a Parse file pointer. `Parse::File` has helper methods to upload Parse files directly to Parse and manage file associations with your classes. Using our Song class example:
|
209
290
|
|
210
291
|
```ruby
|
@@ -212,7 +293,8 @@ This class represents a Parse file pointer. `Parse::File` has helper methods to
|
|
212
293
|
file = song.audio_file # Parse::File
|
213
294
|
file.url # URL in the Parse file storage system
|
214
295
|
|
215
|
-
|
296
|
+
file = File.open("file_path.jpg")
|
297
|
+
contents = file.read
|
216
298
|
file = Parse::File.new("myimage.jpg", contents , "image/jpeg")
|
217
299
|
file.saved? # false. Hasn't been uploaded to Parse
|
218
300
|
file.save # uploads to Parse.
|
@@ -226,7 +308,25 @@ This class represents a Parse file pointer. `Parse::File` has helper methods to
|
|
226
308
|
|
227
309
|
```
|
228
310
|
|
229
|
-
|
311
|
+
The default MIME type for all files is `iamge/jpeg`. This can be default can be changed by setting a value to `Parse::File.default_mime_type`. Other ways of creating a `Parse::File` are provided below. The created Parse::File is not uploaded until you call `save`.
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
# urls
|
315
|
+
file = Parse::File.new "http://example.com/image.jpg"
|
316
|
+
file.name # image.jpg
|
317
|
+
|
318
|
+
# file objects
|
319
|
+
file = Parse::File.new File.open("myimage.jpg")
|
320
|
+
|
321
|
+
# non-image files work too
|
322
|
+
file = Parse::File.new "http://www.example.com/something.pdf"
|
323
|
+
file.mime_type = "application/octet-stream" #set the mime-type!
|
324
|
+
|
325
|
+
# or another Parse::File object
|
326
|
+
file = Parse::File.new parse_file
|
327
|
+
```
|
328
|
+
|
329
|
+
### Parse::Date
|
230
330
|
This class manages dates in the special JSON format it requires for properties of type `:date`. `Parse::Date` subclasses `DateTime`, which allows you to use any features or methods available to `DateTime` with `Parse::Date`. While the conversion between `Time` and `DateTime` objects to a `Parse::Date` object is done implicitly for you, you can use the added special methods, `DateTime#parse_date` and `Time#parse_date`, for special occasions.
|
231
331
|
|
232
332
|
```ruby
|
@@ -237,11 +337,11 @@ This class manages dates in the special JSON format it requires for properties o
|
|
237
337
|
|
238
338
|
One important note with dates, is that `created_at` and `updated_at` columns do not follow this convention all the time. Depending on the Cloud Code SDK, they can be the Parse ISO hash date format or the `iso8601` string format. By default, these are serialized as `iso8601` when sent as responses to Parse for backwards compatibility with some clients. To use the Parse ISO hash format for these fields instead, set `Parse::Object.disable_serialized_string_date = true`.
|
239
339
|
|
240
|
-
|
241
|
-
This class manages the GeoPoint data type that Parse provides to support geo-queries. To define a GeoPoint property, use the `:geopoint` data type.
|
340
|
+
### Parse::GeoPoint
|
341
|
+
This class manages the GeoPoint data type that Parse provides to support geo-queries. To define a GeoPoint property, use the `:geopoint` data type. Please note that latitudes should not be between -90.0 and 90.0, and longitudes should be between -180.0 and 180.0.
|
242
342
|
|
243
343
|
```ruby
|
244
|
-
class
|
344
|
+
class PlaceObject < Parse::Object
|
245
345
|
property :location, :geopoint
|
246
346
|
end
|
247
347
|
|
@@ -249,15 +349,27 @@ This class manages the GeoPoint data type that Parse provides to support geo-que
|
|
249
349
|
los_angeles = Parse::GeoPoint.new [34.0192341, -118.970792]
|
250
350
|
san_diego == los_angeles # false
|
251
351
|
|
252
|
-
|
352
|
+
place = PlaceObject.new
|
353
|
+
place.location = san_diego
|
354
|
+
place.save
|
355
|
+
```
|
253
356
|
|
254
|
-
|
255
|
-
|
256
|
-
|
357
|
+
#### Calculating Distances between locations
|
358
|
+
We include helper methods to calculate distances between GeoPoints: `distance_in_miles` and `distance_in_km`.
|
359
|
+
|
360
|
+
```ruby
|
361
|
+
san_diego = Parse::GeoPoint.new(32.8233, -117.6542)
|
362
|
+
los_angeles = Parse::GeoPoint.new [34.0192341, -118.970792]
|
257
363
|
|
364
|
+
# Haversine calculations
|
365
|
+
san_diego.distance_in_miles(los_angeles)
|
366
|
+
# ~112.33 miles
|
367
|
+
|
368
|
+
san_diego.distance_in_km(los_angeles)
|
369
|
+
# ~180.793 km
|
258
370
|
```
|
259
371
|
|
260
|
-
|
372
|
+
### Parse::Bytes
|
261
373
|
The `Bytes` data type represents the storage format for binary content in a Parse column. The content is needs to be encoded into a base64 string.
|
262
374
|
|
263
375
|
```ruby
|
@@ -269,13 +381,31 @@ The `Bytes` data type represents the storage format for binary content in a Pars
|
|
269
381
|
decoded = bytes.decoded # same as Base64.decode64
|
270
382
|
```
|
271
383
|
|
272
|
-
|
384
|
+
## Modeling and Subclassing
|
385
|
+
For the general case, your Parse classes should inherit from `Parse::Object`. `Parse::Object` utilizes features from `ActiveModel` to add several features to each instance of your subclass. These include `Dirty`, `Conversion`, `Callbacks`, `Naming` and `Serializers::JSON`.
|
386
|
+
|
387
|
+
To get started use the `property` and `has_many` methods to setup declarations for your fields. Properties define literal values that are columns in your Parse class. These can be any of the base Parse data types. You will not need to define classes for the basic Parse class types - this includes "\_User", "\_Installation", "\_Session" and "\_Role". These are mapped to `Parse::User`, `Parse::Installation`, `Parse::Session` and `Parse::Role` respectively.
|
388
|
+
|
389
|
+
To get started, you define your classes based on `Parse::Object`. By default, the name of the class is used as the name of the remote Parse class. For a class `Post`, we will assume there is a remote camel-cased Parse table called `Post`. If you need to map the local class name to a different remote class, use the `parse_class` method.
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
class Post < Parse::Object
|
393
|
+
# assumes Parse class "Post"
|
394
|
+
end
|
395
|
+
|
396
|
+
class Commentary < Parse::Object
|
397
|
+
# set remote class "Comment"
|
398
|
+
parse_class "Comment"
|
399
|
+
end
|
400
|
+
```
|
401
|
+
|
402
|
+
### Defining Properties
|
273
403
|
Properties are considered a literal-type of association. This means that a defined local property maps directly to a column name for that remote Parse class which contain the value. **All properties are implicitly formatted to map to a lower-first camelcase version in Parse (remote).** Therefore a local property defined as `like_count`, would be mapped to the remote column of `likeCount` automatically. The only special behavior to this rule is the `:id` property which maps to `objectId` in Parse. This implicit conversion mapping is the default behavior, but can be changed on a per-property basis. All Parse data types are supported and all Parse::Object subclasses already provide definitions for `:id` (objectId), `:created_at` (createdAt), `:updated_at` (updatedAt) and `:acl` (ACL) properties.
|
274
404
|
|
275
405
|
- **:string** (_default_) - a generic string.
|
276
406
|
- **:integer** - basic number.
|
277
407
|
- **:float** - a floating numeric value.
|
278
|
-
- **:boolean** - true/false value.
|
408
|
+
- **:boolean** - true/false value. (_alias: `:bool`_).
|
279
409
|
- **:date** - a Parse date type. Maps to `Parse::Date`.
|
280
410
|
- **:array** - a collection of heterogeneous items. Maps to `Parse::CollectionProxy`.
|
281
411
|
- **:file** - a Parse file type. Maps to `Parse::File`.
|
@@ -344,7 +474,7 @@ post.tags.remove "stuff"
|
|
344
474
|
post.save # commit changes
|
345
475
|
```
|
346
476
|
|
347
|
-
|
477
|
+
#### Accessor Aliasing
|
348
478
|
To enable easy conversion between incoming Parse attributes, which may be different than the locally labeled attribute, we make use of aliasing accessors with their remote field names. As an example, for a `Post` instance and its `publish_date` property, it would have an accessor defined for both `publish_date` and `publishDate` (or whatever value you passed as the `:field` option) that map to the same attribute. We highly discourage turning off this feature, but if you need to, you can pass the value of `false` to the `:alias` option when defining the property.
|
349
479
|
|
350
480
|
```ruby
|
@@ -360,13 +490,13 @@ post.SEO # the alias method since 'field: "SEO"'
|
|
360
490
|
#### Property Options
|
361
491
|
These are the supported options when defining properties. Parse::Objects are backed by `ActiveModel`, which means you can add additional validations and features supported by that library.
|
362
492
|
|
363
|
-
|
493
|
+
##### `:required => (true|false)`
|
364
494
|
This option provides information to the property builder that it is a required property. The requirement is not strongly enforced for a save, which means even though the value for the property may not be present, saves and updates can be successfully performed. However, the setting `required` to true, it will set some ActiveModel validations on the property to be used when calling `valid?`. By default it will add a `validates_presence_of` for the property key. If the data type of the property is either `:integer` or `:float`, it will also add a `validates_numericality_of` validation. Default `false`.
|
365
495
|
|
366
|
-
|
496
|
+
##### `:field => (string)`
|
367
497
|
This option allows you to set the name of the remote column for the Parse table. Using this will explicitly set the remote property name to the value of this option. The value provided for this option will affect the name of the alias method that is generated when `alias` option is used. **By default, the name of the remote column is the lower-first camelcase version of the property name. As an example, for a property with key `:my_property_name`, the framework will implicitly assume that the remote column is `myPropertyName`.**
|
368
498
|
|
369
|
-
|
499
|
+
##### `:default => (value|proc)`
|
370
500
|
This option provides you to set a default value for a specific property when the getter accessor method is used and the internal value of the instance object's property is nil. It can either take a literal value or a Proc/lambda.
|
371
501
|
|
372
502
|
```ruby
|
@@ -377,10 +507,11 @@ class SomeClass < Parse::Object
|
|
377
507
|
property :date, default: lambda { |x| DateTime.now }
|
378
508
|
end
|
379
509
|
```
|
380
|
-
|
510
|
+
|
511
|
+
##### `:alias => (true|false)`
|
381
512
|
It is highly recommended that this is set to true, which is the default. This option allows for the generation of the additional accessors with the value of `:field`. By allowing two accessors methods, aliased to each other, allows for easier importing and automatic object instantiation based on Parse object JSON data into the Parse::Object subclass.
|
382
513
|
|
383
|
-
|
514
|
+
##### `:symbolize => (true|false)`
|
384
515
|
This option is only available for fields with data type of `:string`. This allows you to utilize the values for this property as symbols instead of the literal strings, which is Parse's storage format. This feature is useful if a particular property represents a set of enumerable states described in string form. As an example, if you have a `Post` object which has a set of publish states stored in Parse as "draft","scheduled", and "published" - we can use ruby symbols to make our code easier.
|
385
516
|
|
386
517
|
```ruby
|
@@ -397,7 +528,7 @@ if post.state == :draft
|
|
397
528
|
end
|
398
529
|
```
|
399
530
|
|
400
|
-
|
531
|
+
##### Overriding Property Accessors
|
401
532
|
When a `property` is defined, special accessors are created for it. It is not recommended that you override the generated accessors for the properties you have defined.
|
402
533
|
|
403
534
|
### Associations
|
@@ -539,11 +670,9 @@ Options for `has_many` are the same as the `belongs_to` counterpart with support
|
|
539
670
|
###### `:through => (:array|:relation)`
|
540
671
|
This sets the type of the `has_many` relation. If `:relation` is set, it tells the framework that the column defined is of type Parse Relation. The default value is `:array`, which defines the column in Parse as being an array of Parse pointer objects.
|
541
672
|
|
542
|
-
## Creating, Saving and
|
673
|
+
## Creating, Saving and Deleting Records
|
543
674
|
This section provides some of the basic methods when creating, updating and deleting objects from Parse. To illustrate the various methods available for saving Parse records, we use this example class:
|
544
675
|
|
545
|
-
#### Examples
|
546
|
-
|
547
676
|
```ruby
|
548
677
|
|
549
678
|
class Artist < Parse::Object
|
@@ -561,21 +690,7 @@ class Song < Parse::Object
|
|
561
690
|
end
|
562
691
|
```
|
563
692
|
|
564
|
-
|
565
|
-
By default, we return `true` or `false` for save and destroy operations. If you prefer to have `Parse::Object` raise an exception instead, you can tell to do so either globally or on a per-model basis. When a save fails, it will raise a `Parse::SaveFailureError`.
|
566
|
-
|
567
|
-
```ruby
|
568
|
-
Parse::Model.raise_on_save_failure = true # globally across all models
|
569
|
-
Song.raise_on_save_failure = true # per-model
|
570
|
-
|
571
|
-
# or per-instance raise on failure
|
572
|
-
song.save!
|
573
|
-
|
574
|
-
```
|
575
|
-
|
576
|
-
When enabled, if an error is returned by Parse due to saving or destroying a record, due to your `before_save` or `before_delete` validation cloud code triggers, `Parse::Object` will return the a `Parse::SaveFailureError` exception type. This exception has an instance method of `#object` which contains the object that failed to save.
|
577
|
-
|
578
|
-
#### Create
|
693
|
+
### Create
|
579
694
|
To create a new object you can call `#new` while passing a hash of attributes you want to set. You can then use the property accessors to also modify individual properties. As you modify properties, you can access dirty tracking state and data using the generated [`ActiveModel::Dirty`](http://api.rubyonrails.org/classes/ActiveModel/Dirty.html) features. When you are ready to commit the new object to Parse, you can call `#save`.
|
580
695
|
|
581
696
|
```ruby
|
@@ -631,7 +746,7 @@ The above will search for a Song with name 'Long Way Home'. If it does not find
|
|
631
746
|
|
632
747
|
In the above case, if a Song is not found with name 'Long Way Home', the new instance will be created with `name` set to 'Other Way Home' and `released` set to `DateTime.now`.
|
633
748
|
|
634
|
-
|
749
|
+
### Saving
|
635
750
|
To commit a new record or changes to an existing record to Parse, use the `#save` method. The method will automatically detect whether it is a new object or an existing one and call the appropriate workflow. The use of ActiveModel dirty tracking allows us to send only the changes that were made to the object when saving. **Saving a record will take care of both saving all the changed properties, and associations. However, any modified linked objects (ex. belongs_to) need to be saved independently.**
|
636
751
|
|
637
752
|
```ruby
|
@@ -660,7 +775,21 @@ To commit a new record or changes to an existing record to Parse, use the `#save
|
|
660
775
|
|
661
776
|
The save operation can handle both creating and updating existing objects. If you do not want to update the association data of a changed object, you may use the `#update` method to only save the changed property values. In the case where you want to force update an object even though it has not changed, to possibly trigger your `before_save` hooks, you can use the `#update!` method.
|
662
777
|
|
663
|
-
|
778
|
+
#### Raising an exception when save fails
|
779
|
+
By default, we return `true` or `false` for save and destroy operations. If you prefer to have `Parse::Object` raise an exception instead, you can tell to do so either globally or on a per-model basis. When a save fails, it will raise a `Parse::SaveFailureError`.
|
780
|
+
|
781
|
+
```ruby
|
782
|
+
Parse::Model.raise_on_save_failure = true # globally across all models
|
783
|
+
Song.raise_on_save_failure = true # per-model
|
784
|
+
|
785
|
+
# or per-instance raise on failure
|
786
|
+
song.save!
|
787
|
+
|
788
|
+
```
|
789
|
+
|
790
|
+
When enabled, if an error is returned by Parse due to saving or destroying a record, due to your `before_save` or `before_delete` validation cloud code triggers, `Parse::Object` will return the a `Parse::SaveFailureError` exception type. This exception has an instance method of `#object` which contains the object that failed to save.
|
791
|
+
|
792
|
+
### Modifying Associations
|
664
793
|
Similar to `:array` types of properties, a `has_many` association is backed by a collection proxy class and requires the use of `#add` and `#remove` to modify the contents of the association in order for it to correctly manage changes and updates with Parse. Using `has_many` for associations has the additional functionality that we will only add items to the association if they are of a `Parse::Pointer` or `Parse::Object` type. By default, these associations are fetched with only pointer data. To fetch all the objects in the association, you can call `#fetch` or `#fetch!` on the collection. Note that because the framework supports chaining, it is better to only request the objects you need by utilizing their accessors.
|
665
794
|
|
666
795
|
```ruby
|
@@ -721,7 +850,20 @@ The `has_many` Parse Relation associations are handled similarly as in the array
|
|
721
850
|
|
722
851
|
```
|
723
852
|
|
724
|
-
|
853
|
+
### Batch Save Requests
|
854
|
+
Batch requests are supported implicitly and intelligently through an extension of array. When an array of `Parse::Object` subclasses is saved, Parse-Stack will batch all possible save operations for the objects in the array that have changed. It will also batch save 50 at a time until all items in the array are saved. *Note: Parse does not allow batch saving Parse::User objects.*
|
855
|
+
|
856
|
+
```ruby
|
857
|
+
songs = Songs.first 1000 #first 1000 songs
|
858
|
+
songs.each do |song|
|
859
|
+
.... modify them ...
|
860
|
+
end
|
861
|
+
|
862
|
+
# will batch save 50 items at a time until all are saved.
|
863
|
+
songs.save
|
864
|
+
```
|
865
|
+
|
866
|
+
### Magic `save_all`
|
725
867
|
By default, all Parse queries have a maximum fetch limit of 1000. While using the `:max` option, `Parse::Stack` can increase this up to 11,000. In the cases where you need to update a large number of objects, you can utilize the `Parse::Object#save_all` method
|
726
868
|
to fetch, modify and save objects.
|
727
869
|
|
@@ -736,7 +878,7 @@ This methodology works by continually fetching and saving older records related
|
|
736
878
|
end
|
737
879
|
```
|
738
880
|
|
739
|
-
|
881
|
+
### Deleting
|
740
882
|
You can destroy a Parse record, just call the `#destroy` method. It will return a boolean value whether it was successful.
|
741
883
|
|
742
884
|
```ruby
|
@@ -812,14 +954,20 @@ This also works for all associations types.
|
|
812
954
|
The `Parse::Query` class provides the lower-level querying interface for your Parse tables using the default `Parse::Client` session created when `setup()` was called. This component can be used on its own without defining your models as all results are provided in hash form. By convention in Ruby (see [Style Guide](https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars)), symbols and variables are expressed in lower_snake_case form. Parse, however, prefers column names in **lower-first camel case** (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. As an additional exception to this rule, the field key of `id` will automatically be converted to the `objectId` field when used. This feature can be overridden by changing the value of `Parse::Query.field_formatter`.
|
813
955
|
|
814
956
|
```ruby
|
815
|
-
|
816
|
-
|
957
|
+
# default uses :columnize
|
958
|
+
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
|
959
|
+
query.compile_where # {"fieldOne"=>1, "fieldTwo"=>2, "fieldThree"=>3}
|
960
|
+
|
961
|
+
# turn off
|
962
|
+
Parse::Query.field_formatter = nil
|
963
|
+
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
|
964
|
+
query.compile_where # {"field_one"=>1, "FieldTwo"=>2, "Field_Three"=>3}
|
817
965
|
|
818
|
-
|
819
|
-
|
966
|
+
# force everything camel case
|
967
|
+
Parse::Query.field_formatter = :camelize
|
968
|
+
query = Parse::User.query :field_one => 1, :FieldTwo => 2, :Field_Three => 3
|
969
|
+
query.compile_where # {"FieldOne"=>1, "FieldTwo"=>2, "FieldThree"=>3}
|
820
970
|
|
821
|
-
# force everything camel case
|
822
|
-
Parse::Query.field_formatter = :camelize
|
823
971
|
```
|
824
972
|
|
825
973
|
Simplest way to perform query, is to pass the Parse class as the first parameter and the set of expressions.
|
@@ -829,7 +977,10 @@ Simplest way to perform query, is to pass the Parse class as the first parameter
|
|
829
977
|
# or with Object classes
|
830
978
|
query = Song.query({ .. expressions ..})
|
831
979
|
|
832
|
-
#
|
980
|
+
# Print the prepared query
|
981
|
+
query.prepared
|
982
|
+
|
983
|
+
# Get results
|
833
984
|
query.results # get results as Parse::Object(s)
|
834
985
|
query.results(raw: true) # get the raw hash results
|
835
986
|
|
@@ -851,34 +1002,7 @@ For large results set where you may want to operate on objects and may not need
|
|
851
1002
|
|
852
1003
|
```
|
853
1004
|
|
854
|
-
|
855
|
-
If you only need to know the result count for a query, provide count a non-zero value. However, if you need to perform a count query, use `count()` method instead. As a reminder, there are a few [caveats to counting records as detailed by Parse](https://parse.com/docs/rest/guide#queries-counting-objects).
|
856
|
-
|
857
|
-
```ruby
|
858
|
-
# get number of songs with a play_count > 10
|
859
|
-
Song.count :play_count.gt => 10
|
860
|
-
|
861
|
-
# same
|
862
|
-
query = Parse::Query.new("Song")
|
863
|
-
query.where :play_count.gt => 10
|
864
|
-
query.count
|
865
|
-
|
866
|
-
```
|
867
|
-
|
868
|
-
#### Compound Queries (or)
|
869
|
-
If you want to find objects that are from one of several queries, you can combine them in an "or" clause using the `|` operator.
|
870
|
-
|
871
|
-
```ruby
|
872
|
-
# use | for combining queries
|
873
|
-
or_query = query1 | query2 | query3.....
|
874
|
-
|
875
|
-
# Find songs whose like count is < 10 OR greater than 100
|
876
|
-
or_query = Song.query(:like_count.gt < 10) | Song.query(:like_count.gt > 100)
|
877
|
-
results = or_query.results
|
878
|
-
|
879
|
-
```
|
880
|
-
|
881
|
-
#### Results Caching
|
1005
|
+
### Results Caching
|
882
1006
|
When a query API is made, the results are cached in the query object in case you need access to the results multiple times. This is only true as long as no modifications to the query parameters are made. You can force clear the locally stored results by calling `clear()` on the query instance.
|
883
1007
|
|
884
1008
|
```ruby
|
@@ -895,10 +1019,24 @@ When a query API is made, the results are cached in the query object in case you
|
|
895
1019
|
|
896
1020
|
```
|
897
1021
|
|
898
|
-
###
|
1022
|
+
### Counting
|
1023
|
+
If you only need to know the result count for a query, provide count a non-zero value. However, if you need to perform a count query, use `count()` method instead. As a reminder, there are a few [caveats to counting records as detailed by Parse](https://parse.com/docs/rest/guide#queries-counting-objects).
|
1024
|
+
|
1025
|
+
```ruby
|
1026
|
+
# get number of songs with a play_count > 10
|
1027
|
+
Song.count :play_count.gt => 10
|
1028
|
+
|
1029
|
+
# same
|
1030
|
+
query = Parse::Query.new("Song")
|
1031
|
+
query.where :play_count.gt => 10
|
1032
|
+
query.count
|
1033
|
+
|
1034
|
+
```
|
1035
|
+
|
1036
|
+
### Query Expressions
|
899
1037
|
The set of supported expressions based on what is available through the Parse REST API. _For those who don't prefer the DataMapper style syntax, we have provided method accessors for each of the expressions._
|
900
1038
|
|
901
|
-
|
1039
|
+
#### :order
|
902
1040
|
Specify a field to sort by.
|
903
1041
|
|
904
1042
|
```ruby
|
@@ -910,7 +1048,7 @@ Specify a field to sort by.
|
|
910
1048
|
Song.all :order => [:like_count.desc, :name]
|
911
1049
|
```
|
912
1050
|
|
913
|
-
|
1051
|
+
#### :keys
|
914
1052
|
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. _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._
|
915
1053
|
|
916
1054
|
```ruby
|
@@ -921,7 +1059,7 @@ Restrict the fields returned by the query. This is useful for larger query resul
|
|
921
1059
|
Song.all :keys => [:name,:artist]
|
922
1060
|
```
|
923
1061
|
|
924
|
-
|
1062
|
+
#### :includes
|
925
1063
|
Use on Pointer columns to return the full object. You may chain multiple columns with the `.` operator.
|
926
1064
|
|
927
1065
|
```ruby
|
@@ -936,7 +1074,7 @@ Use on Pointer columns to return the full object. You may chain multiple columns
|
|
936
1074
|
|
937
1075
|
```
|
938
1076
|
|
939
|
-
|
1077
|
+
#### :limit
|
940
1078
|
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 an empty result set is received or the `:skip` limit is reached (10,000). When utilizing `all()`, `:max` is the default option for `:limit`.
|
941
1079
|
|
942
1080
|
```ruby
|
@@ -945,7 +1083,7 @@ Limit the number of objects returned by the query. The default is 100, with Pars
|
|
945
1083
|
Song.all :limit => :max # up to 11,000 records (theoretical).
|
946
1084
|
```
|
947
1085
|
|
948
|
-
|
1086
|
+
#### :skip
|
949
1087
|
Use with limit to paginate through results. Default is 0 with maximum value being 10,000.
|
950
1088
|
|
951
1089
|
```ruby
|
@@ -953,114 +1091,296 @@ Use with limit to paginate through results. Default is 0 with maximum value bein
|
|
953
1091
|
Song.all :limit => 3, :skip => 10
|
954
1092
|
```
|
955
1093
|
|
956
|
-
|
957
|
-
|
1094
|
+
#### :cache
|
1095
|
+
A true/false value. If you are using the built-in caching middleware, `Parse::Middleware::Caching`, it will prevent it from using a previously cached result if available. The default value is `true`.
|
958
1096
|
|
959
1097
|
```ruby
|
960
|
-
|
961
|
-
|
1098
|
+
# don't use a cached result if available
|
1099
|
+
Song.all limit: 3, cache: false
|
962
1100
|
```
|
963
1101
|
|
964
|
-
|
965
|
-
|
1102
|
+
#### :use_master_key
|
1103
|
+
A true/false value. If you provided a master key as part of `Parse.setup()`, it will be sent on every request. However, if you wish to disable sending the master key on a particular request in order for the record ACLs to be enforced, you may pass `false`. If `false` is passed, caching will be disabled for this request.
|
966
1104
|
|
967
1105
|
```ruby
|
968
|
-
|
1106
|
+
# disable sending the master key in the request if configured
|
1107
|
+
Song.all limit: 3, use_master_key: false
|
1108
|
+
```
|
1109
|
+
|
1110
|
+
#### :session_token
|
1111
|
+
A Parse session token string. If you would like to perform a query as a particular user, you may pass their session token in the query. This will make sure that the query is performed on behalf (and with the priviledges) of that user which will cause record ACLs to be enforced. If a session token is provided, caching will be disabled for this request.
|
1112
|
+
|
1113
|
+
```ruby
|
1114
|
+
# disable sending the master key in the request if configured
|
1115
|
+
Song.all limit: 3, session_token: "<session_token>"
|
1116
|
+
```
|
1117
|
+
|
1118
|
+
#### :where
|
1119
|
+
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. See the section `Query Constraints` for examples of available query constraints.
|
1120
|
+
|
1121
|
+
```ruby
|
1122
|
+
# parts of a single where constraint
|
1123
|
+
{ :column.constraint => value }
|
1124
|
+
```
|
1125
|
+
|
1126
|
+
## Query Constraints
|
1127
|
+
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](http://parseplatform.github.io/docs/rest/guide/#queries). 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.
|
1128
|
+
|
1129
|
+
#### Equals
|
1130
|
+
Default query constraint for matching a field to a single value.
|
1131
|
+
|
1132
|
+
```ruby
|
1133
|
+
q.where :field => value
|
1134
|
+
# (alias) :field.eq => value
|
1135
|
+
```
|
1136
|
+
|
1137
|
+
#### Less Than
|
1138
|
+
Equivalent to the `$lt` Parse query operation. The alias `before` is provided for readability.
|
1139
|
+
|
1140
|
+
```ruby
|
1141
|
+
q.where :field.lt => value
|
1142
|
+
# or alias
|
1143
|
+
q.where :field.before => value
|
1144
|
+
# ex. :createdAt.before => DateTime.now
|
1145
|
+
```
|
969
1146
|
|
1147
|
+
#### Less Than or Equal To
|
1148
|
+
Equivalent to the `$lte` Parse query operation. The alias `on_or_before` is provided for readability.
|
970
1149
|
|
971
|
-
|
972
|
-
|
1150
|
+
```ruby
|
1151
|
+
q.where :field.lte => value
|
1152
|
+
# or alias
|
1153
|
+
q.where :field.on_or_before => value
|
1154
|
+
# ex. :createdAt.on_or_before => DateTime.now
|
1155
|
+
```
|
1156
|
+
|
1157
|
+
#### Greater Than
|
1158
|
+
Equivalent to the `$gt` Parse query operation. The alias `after` is provided for readability.
|
1159
|
+
|
1160
|
+
```ruby
|
1161
|
+
q.where :field.gt => value
|
1162
|
+
# or alias
|
1163
|
+
q.where :field.after => value
|
1164
|
+
# ex. :createdAt.after => DateTime.now
|
1165
|
+
```
|
1166
|
+
|
1167
|
+
#### Greater Than or Equal
|
1168
|
+
Equivalent to the `$gte` Parse query operation. The alias `on_or_after` is provided for readability.
|
1169
|
+
|
1170
|
+
```ruby
|
1171
|
+
q.where :field.gte => value
|
1172
|
+
# or alias
|
1173
|
+
q.where :field.on_or_after => value
|
1174
|
+
# ex. :createdAt.on_or_after => DateTime.now
|
1175
|
+
```
|
973
1176
|
|
974
|
-
|
975
|
-
|
976
|
-
# alias to `lt`; useful when dealing with dates
|
977
|
-
q.where :field.before => value
|
1177
|
+
#### Not Equal To
|
1178
|
+
Equivalent to the `$ne` Parse query operation. Where a particular field is not equal to value.
|
978
1179
|
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
q.where :field.on_or_before => value
|
1180
|
+
```ruby
|
1181
|
+
q.where :field.not => value
|
1182
|
+
```
|
983
1183
|
|
984
|
-
|
985
|
-
|
986
|
-
# alias to `gt`; useful when dealing with dates
|
987
|
-
q.where :field.after => value
|
1184
|
+
#### Nullability Check
|
1185
|
+
Provides a mechanism using the equality operator to check for `(undefined)` values.
|
988
1186
|
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
q.where :field.on_or_after => value
|
1187
|
+
```ruby
|
1188
|
+
q.where :field.null => true|false
|
1189
|
+
```
|
993
1190
|
|
994
|
-
|
995
|
-
|
1191
|
+
#### Exists
|
1192
|
+
Equivalent to the `#exists` Parse query operation. Checks whether a value is set for key. The difference between this operation and the nullability check is when using compound queries with location.
|
996
1193
|
|
997
|
-
|
998
|
-
|
1194
|
+
```ruby
|
1195
|
+
q.where :field.exists => true|false
|
1196
|
+
```
|
999
1197
|
|
1000
|
-
|
1001
|
-
|
1198
|
+
#### Contained In
|
1199
|
+
Equivalent to the `$in` Parse query operation. Checks whether the value in the column field is contained in the set of values in the array.
|
1002
1200
|
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1201
|
+
```ruby
|
1202
|
+
# ex. :score.in => [1,3,5,7,9]
|
1203
|
+
q.where :field.in => [item1,item2,...]
|
1204
|
+
# alias
|
1205
|
+
q.where :field.contained_in => [item1,item2,...]
|
1206
|
+
```
|
1006
1207
|
|
1007
|
-
|
1008
|
-
|
1208
|
+
#### Not Contained In
|
1209
|
+
Equivalent to the `$nin` Parse query operation. Checks whether the value in the column field is __not__ contained in the set of values in the array.
|
1009
1210
|
|
1010
|
-
|
1211
|
+
```ruby
|
1212
|
+
# ex. :player_name.not_in => ['Jonathan', 'Dario', 'Shawn']
|
1213
|
+
q.where :field.not_in => [item1,item2,...]
|
1214
|
+
# alias
|
1215
|
+
q.where :field.not_contained_in => [item1,item2,...]
|
1216
|
+
```
|
1217
|
+
|
1218
|
+
#### Contains All
|
1219
|
+
Equivalent to the `$all` Parse query operation. Checks whether the value in the column field contains all of the given values provided in the array. Note that the `field` column must be of type `Array` in your Parse class.
|
1220
|
+
|
1221
|
+
```ruby
|
1222
|
+
# ex. :array_key.all => [2,3,4]
|
1011
1223
|
q.where :field.all => [item1, item2,...]
|
1224
|
+
# alias
|
1012
1225
|
q.where :field.contains_all => [item1,item2,...]
|
1226
|
+
```
|
1227
|
+
|
1228
|
+
#### Regex Matching
|
1229
|
+
Equivalent to the `$regex` Parse query operation. Requires that a field value match a regular expression.
|
1230
|
+
|
1231
|
+
```ruby
|
1232
|
+
# ex. :name.like => /Bob/i
|
1233
|
+
q.where :field.like => /ruby_regex/i
|
1234
|
+
# alias
|
1235
|
+
q.where :field.regex => /abc/
|
1236
|
+
```
|
1013
1237
|
|
1014
|
-
|
1015
|
-
|
1016
|
-
q.where :field.regex => /abc/ # alias
|
1238
|
+
#### Select
|
1239
|
+
Equivalent to the `$select` Parse query operation. This matches a value for a key in the result of a different query.
|
1017
1240
|
|
1018
|
-
|
1019
|
-
|
1020
|
-
# ex. q.where :city.select => Artist.where(:total_plays.gt => 50, :key => "city")
|
1241
|
+
```ruby
|
1242
|
+
q.where :field.select => { key: "field", query: query }
|
1021
1243
|
|
1022
|
-
|
1023
|
-
|
1244
|
+
# example
|
1245
|
+
value = { key: 'city', query: Artist.where(:fan_count.gt => 50) }
|
1246
|
+
q.where :hometown.select => value
|
1024
1247
|
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1248
|
+
# if the local field is the same name as the foreign table field, you can omit hash
|
1249
|
+
# assumes key: 'city'
|
1250
|
+
q.where :city.select => Artist.where(:fan_count.gt => 50)
|
1251
|
+
```
|
1028
1252
|
|
1029
|
-
|
1030
|
-
|
1031
|
-
q.where :field.not_in_query => query # alias
|
1253
|
+
#### Reject
|
1254
|
+
Equivalent to the `$dontSelect` Parse query operation. Requires that a field's value not match a value for a key in the result of a different query.
|
1032
1255
|
|
1033
|
-
|
1034
|
-
|
1256
|
+
```ruby
|
1257
|
+
q.where :field.reject => { key: :other_field, query: query }
|
1035
1258
|
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
q.where :field.near => [lat,lng,miles]
|
1259
|
+
# example
|
1260
|
+
value = { key: 'city', query: Artist.where(:fan_count.gt => 50) }
|
1261
|
+
q.where :hometown.reject => value
|
1040
1262
|
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1263
|
+
# if the local field is the same name as the foreign table field, you can omit hash
|
1264
|
+
# assumes key: 'city'
|
1265
|
+
q.where :city.reject => Artist.where(:fan_count.gt => 50)
|
1266
|
+
```
|
1044
1267
|
|
1045
|
-
|
1046
|
-
|
1268
|
+
#### Matches Query
|
1269
|
+
Equivalent to the `$inQuery` Parse query operation. Useful if you want to retrieve objects where a field contains an object that matches another query.
|
1270
|
+
|
1271
|
+
```ruby
|
1272
|
+
q.where :field.matches => query
|
1273
|
+
# ex. :post.matches => Post.where(:image.exists => true )
|
1274
|
+
q.where :field.in_query => query # alias
|
1047
1275
|
```
|
1048
1276
|
|
1049
|
-
|
1050
|
-
|
1277
|
+
#### Excludes Query
|
1278
|
+
Equivalent to the `$notInQuery` Parse query operation. Useful if you want to retrieve objects where a field contains an object that does not match another query.
|
1051
1279
|
|
1052
1280
|
```ruby
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
# for https://api.parse.com/1/classes/_User
|
1281
|
+
q.where :field.excludes => query
|
1282
|
+
# ex. :post.excludes => Post.where(:image.exists => true
|
1283
|
+
q.where :field.not_in_query => query # alias
|
1057
1284
|
```
|
1058
1285
|
|
1059
|
-
|
1286
|
+
### Geo Queries
|
1287
|
+
Equivalent to the `$nearSphere` Parse query operation. This is only applicable if the field is of type `GeoPoint`. This will query Parse and return a list of results ordered by distance with the nearest object being first.
|
1060
1288
|
|
1061
1289
|
```ruby
|
1062
|
-
|
1063
|
-
|
1290
|
+
q.where :field.near => geopoint
|
1291
|
+
|
1292
|
+
# example
|
1293
|
+
geopoint = Parse::GeoPoint.new(30.0, -20.0)
|
1294
|
+
PlaceObject.all :location.near => geopoint
|
1295
|
+
```
|
1296
|
+
|
1297
|
+
#### Max Distance Constraint
|
1298
|
+
If you wish to constrain the geospatial query to a maximum number of __miles__, you can utilize the `max_miles` method on a `Parse::GeoPoint` object. This is equivalent to the `$maxDistanceInMiles` constraint used with `$nearSphere`.
|
1299
|
+
|
1300
|
+
```ruby
|
1301
|
+
q.where :field.near => geopoint.max_miles(distance)
|
1302
|
+
# or provide a triplet includes max miles constraint
|
1303
|
+
q.where :field.near => [lat, lng, miles]
|
1304
|
+
|
1305
|
+
# example
|
1306
|
+
geopoint = Parse::GeoPoint.new(30.0, -20.0)
|
1307
|
+
PlaceObject.all :location.near => geopoint.max_miles(10)
|
1308
|
+
```
|
1309
|
+
|
1310
|
+
We will support `$maxDistanceInKilometers` (for kms) and `$maxDistanceInRadians` (for radian angle) in the future.
|
1311
|
+
|
1312
|
+
#### Bounding Box Constraint
|
1313
|
+
Equivalent to the `$within` Parse query operation and `$box` geopoint constraint. The rectangular bounding box is defined by a southwest point as the first parameter, followed by the a northeast point. Please note that Geo box queries that cross the international date lines are not currently supported by Parse.
|
1314
|
+
|
1315
|
+
```ruby
|
1316
|
+
# GeoPoint bounding box
|
1317
|
+
q.where :field.within_box => [soutwestGeoPoint, northeastGeoPoint]
|
1318
|
+
|
1319
|
+
# example
|
1320
|
+
sw = Parse::GeoPoint.new 32.82, -117.23 # San Diego
|
1321
|
+
ne = Parse::GeoPoint.new 36.12, -115.31 # Las Vegas
|
1322
|
+
|
1323
|
+
# get all PlaceObjects inside this bounding box
|
1324
|
+
PlaceObject.all :location.within_box => [sw,ne]
|
1325
|
+
```
|
1326
|
+
|
1327
|
+
### Relational Queries
|
1328
|
+
Equivalent to the `$relatedTo` Parse query operation. If you want to retrieve objects that are members of a `Relation` field in your Parse class.
|
1329
|
+
|
1330
|
+
```ruby
|
1331
|
+
q.where :field.related_to => pointer
|
1332
|
+
q.where :field.rel => pointer # alias
|
1333
|
+
|
1334
|
+
# example
|
1335
|
+
# find all Users who have liked this post object
|
1336
|
+
post = Post.first
|
1337
|
+
users = Parse::User.all :likes.rel => post
|
1338
|
+
```
|
1339
|
+
|
1340
|
+
### Compound Queries
|
1341
|
+
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.
|
1342
|
+
|
1343
|
+
```ruby
|
1344
|
+
or_query = query1 | query2 | query3 ...
|
1345
|
+
|
1346
|
+
# ex. where wins > 150 || wins < 5
|
1347
|
+
query = Player.where(:wins.gt => 150) | Player.where(:wins.lt => 5)
|
1348
|
+
results = query.results
|
1349
|
+
```
|
1350
|
+
|
1351
|
+
If you do not prefer the syntax you may use the `or_where` method to chain multiple `Parse::Query` instances.
|
1352
|
+
|
1353
|
+
```ruby
|
1354
|
+
query = Player.where(:wins.gt => 150)
|
1355
|
+
query.or_where(:wins.lt => 5)
|
1356
|
+
# where wins > 150 || wins < 5
|
1357
|
+
results = query.results
|
1358
|
+
```
|
1359
|
+
|
1360
|
+
## Cloud Code Functions
|
1361
|
+
You can call on your defined Cloud Code functions using the `call_function()` method. The result will be `nil` in case of errors or the value of the `result` field in the Parse response.
|
1362
|
+
|
1363
|
+
```ruby
|
1364
|
+
params = {}
|
1365
|
+
# use the explicit name of the function
|
1366
|
+
result = Parse.call_function 'functionName', params
|
1367
|
+
|
1368
|
+
# to get the raw Response object
|
1369
|
+
response = Parse.call_function 'functionName', params, raw: true
|
1370
|
+
response.result unless response.error?
|
1371
|
+
```
|
1372
|
+
|
1373
|
+
## Cloud Code Background Jobs
|
1374
|
+
You can trigger background jobs that you have configured in your Parse application as follows.
|
1375
|
+
|
1376
|
+
```ruby
|
1377
|
+
params = {}
|
1378
|
+
# use explicit name of the job
|
1379
|
+
result = Parse.trigger_job :myJobName, params
|
1380
|
+
|
1381
|
+
# to get the raw Response object
|
1382
|
+
response = Parse.trigger_job :myJobName, params, raw: true
|
1383
|
+
response.result unless response.error?
|
1064
1384
|
```
|
1065
1385
|
|
1066
1386
|
## Hooks and Callbacks
|
@@ -1085,6 +1405,18 @@ puts song.name # 'My Title'
|
|
1085
1405
|
|
1086
1406
|
```
|
1087
1407
|
|
1408
|
+
## Schema Upgrades and Migrations
|
1409
|
+
You may change your local Parse ruby classes by adding new properties. To easily propagate the changes to your Parse application (MongoDB), you can call `auto_upgrade!` on the class to perform an non-destructive additive schema change. This will create the new columns in Parse for the properties you have defined in your models. Parse Stack will calculate the changes and only modify the tables which need new columns to be added. *It will not destroy columns or data*
|
1410
|
+
|
1411
|
+
```ruby
|
1412
|
+
# upgrade the a class individually
|
1413
|
+
Song.auto_upgrade!
|
1414
|
+
|
1415
|
+
# upgrade all classes for the default client connection.
|
1416
|
+
Parse.auto_upgrade!
|
1417
|
+
|
1418
|
+
```
|
1419
|
+
|
1088
1420
|
## Push Notifications
|
1089
1421
|
Push notifications are implemented through the `Parse::Push` class. To send push notifications through the REST API, you must enable `REST push enabled?` option in the `Push Notification Settings` section of the `Settings` page in your Parse application. Push notifications targeting uses the Installation Parse class to determine which devices receive the notification. You can provide any query constraint, similar to using `Parse::Query`, in order to target the specific set of devices you want given the columns you have configured in your `Installation` class. The `Parse::Push` class supports many other options not listed here.
|
1090
1422
|
|
@@ -1113,10 +1445,10 @@ Push notifications are implemented through the `Parse::Push` class. To send push
|
|
1113
1445
|
|
1114
1446
|
```
|
1115
1447
|
|
1116
|
-
## Webhooks
|
1117
|
-
Parse Parse allows you to receive Cloud Code webhooks on your own hosted server. The `Parse::Webhooks` class is a lightweight Rack application that routes incoming Cloud Code webhook requests and payloads to locally registered handlers. The payloads are `Parse::Payload` type of objects that represent that data that Parse sends webhook handlers. You can register any of the Cloud Code webhook trigger hooks (`beforeSave`, `afterSave`, `beforeDelete`, `afterDelete`) and function hooks.
|
1448
|
+
## Cloud Code Webhooks
|
1449
|
+
Parse Parse allows you to receive Cloud Code webhooks on your own hosted server. The `Parse::Webhooks` class is a lightweight Rack application that routes incoming Cloud Code webhook requests and payloads to locally registered handlers. The payloads are `Parse::Payload` type of objects that represent that data that Parse sends webhook handlers. You can register any of the Cloud Code webhook trigger hooks (`beforeSave`, `afterSave`, `beforeDelete`, `afterDelete`) and function hooks. If you are using the open source [Parse Server](https://github.com/ParsePlatform/parse-server), you must enable this hooks feature by enabling the environment variable `PARSE_EXPERIMENTAL_HOOKS_ENABLED` on your Parse server.
|
1118
1450
|
|
1119
|
-
###
|
1451
|
+
### Cloud Code functions
|
1120
1452
|
You can use the `route()` method to register handler blocks. The last value returned by the block will be returned back to the client in a success response. If `error!(value)` is called inside the block, we will return the correct Parse error response with the value you provided.
|
1121
1453
|
|
1122
1454
|
```ruby
|
@@ -1152,7 +1484,7 @@ end
|
|
1152
1484
|
|
1153
1485
|
```
|
1154
1486
|
|
1155
|
-
###
|
1487
|
+
### Cloud Code Triggers
|
1156
1488
|
You can register webhooks to handle the different object triggers: `:before_save`, `:after_save`, `:before_delete` and `:after_delete`. The `payload` object, which is an instance of `Parse::Payload`, contains several properties that represent the payload. One of the most important ones is `parse_object`, which will provide you with the instance of your specific Parse object. In `:before_save` triggers, this object already contains dirty tracking information of what has been changed.
|
1157
1489
|
|
1158
1490
|
```ruby
|
@@ -1259,32 +1591,20 @@ end
|
|
1259
1591
|
|
1260
1592
|
```
|
1261
1593
|
|
1262
|
-
|
1263
|
-
You can call on your defined Cloud Code functions using the `call_function()` method. The result will be `nil` in case of errors or the value of the `result` field in the Parse response.
|
1594
|
+
However, we have predefined a few rake tasks you can use in your application. Just require `parse/stack/tasks` in your `Rakefile` and call `Parse::Stack.load_tasks`. This is useful for web frameworks like `Padrino` and `Rails`.
|
1264
1595
|
|
1265
1596
|
```ruby
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1597
|
+
# Rails Rakefile example
|
1598
|
+
require_relative 'config/application'
|
1599
|
+
require 'parse/stack/tasks' # add this line
|
1269
1600
|
|
1270
|
-
|
1271
|
-
|
1272
|
-
response.result unless response.error?
|
1273
|
-
```
|
1274
|
-
|
1275
|
-
## Cloud Code Background Jobs
|
1276
|
-
You can trigger background jobs that you have configured in your Parse application as follows.
|
1601
|
+
Rails.application.load_tasks
|
1602
|
+
Parse::Stack.load_tasks # add this line
|
1277
1603
|
|
1278
|
-
```ruby
|
1279
|
-
params = {}
|
1280
|
-
# use explicit name of the job
|
1281
|
-
result = Parse.trigger_job :myJobName, params
|
1282
|
-
|
1283
|
-
# to get the raw Response object
|
1284
|
-
response = Parse.trigger_job :myJobName, params, raw: true
|
1285
|
-
response.result unless response.error?
|
1286
1604
|
```
|
1287
1605
|
|
1606
|
+
Then you can see the tasks available by typing `rake -T`.
|
1607
|
+
|
1288
1608
|
## Parse REST API Client
|
1289
1609
|
While in most cases you do not have to work with `Parse::Client` directly, you can still utilize it for any raw requests that are not supported by the framework. We provide support for most of the [Parse REST API](https://parse.com/docs/rest/guide#quick-reference) endpoints as helper methods, however you can use the `request()` method to make your own API requests. Parse::Client will handle header authentication, request/response generation and caching.
|
1290
1610
|
|
@@ -1304,8 +1624,20 @@ end
|
|
1304
1624
|
|
1305
1625
|
```
|
1306
1626
|
|
1627
|
+
If you are already have setup a client that is being used by your defined models, you can access the current client with the following API:
|
1628
|
+
|
1629
|
+
```ruby
|
1630
|
+
# current Parse::Client used by this model
|
1631
|
+
client = Song.client
|
1632
|
+
|
1633
|
+
# you can also have multiple clients
|
1634
|
+
client = Parse::Client.session #default client session
|
1635
|
+
client = Parse::Client.session(:other_session)
|
1636
|
+
|
1637
|
+
```
|
1638
|
+
|
1307
1639
|
##### Options
|
1308
|
-
- **
|
1640
|
+
- **app_id**: Your Parse application identifier.
|
1309
1641
|
- **api_key**: Your REST API key corresponding to the provided `application_id`.
|
1310
1642
|
- **master_key**: The master secret key for the application. If this is provided, `api_key` may be unnecessary.
|
1311
1643
|
- **logging**: A boolean value to add additional logging messages.
|
@@ -1314,7 +1646,7 @@ end
|
|
1314
1646
|
- **adapter**: The connection adapter to use. Defaults to `Faraday.default_adapter`.
|
1315
1647
|
|
1316
1648
|
### Request Caching
|
1317
|
-
For high traffic applications that may be performing several server tasks on similar objects, you may utilize request caching. Caching is provided by a the `Parse::Middleware::Caching` class which utilizes a [Moneta store](https://github.com/minad/moneta) object to cache GET url requests that have allowable status codes (ex. HTTP 200,
|
1649
|
+
For high traffic applications that may be performing several server tasks on similar objects, you may utilize request caching. Caching is provided by a the `Parse::Middleware::Caching` class which utilizes a [Moneta store](https://github.com/minad/moneta) object to cache GET url requests that have allowable status codes (ex. HTTP 200, etc). The cache entry for the url will be removed when it is either considered expired (based on the `expires` option) or if a non-GET request is made with the same url. Using this feature appropriately can dramatically reduce your API request usage.
|
1318
1650
|
|
1319
1651
|
```ruby
|
1320
1652
|
store = Moneta.new :Redis, url: 'redis://localhost:6379'
|
@@ -1324,6 +1656,13 @@ Parse.setup(cache: store, expires: 10, ...)
|
|
1324
1656
|
user = Parse::User.first # request made
|
1325
1657
|
same_user = Parse::User.first # cached result
|
1326
1658
|
|
1659
|
+
# you may clear the cache at any time
|
1660
|
+
# clear the cache for the default session
|
1661
|
+
Parse::Client.session.clear_cache!
|
1662
|
+
|
1663
|
+
# or through the client accessor of a model
|
1664
|
+
Song.client.clear_cache!
|
1665
|
+
|
1327
1666
|
```
|
1328
1667
|
|
1329
1668
|
## Installation
|
@@ -1331,7 +1670,7 @@ same_user = Parse::User.first # cached result
|
|
1331
1670
|
Add this line to your application's Gemfile:
|
1332
1671
|
|
1333
1672
|
```ruby
|
1334
|
-
gem 'parse-stack'
|
1673
|
+
gem 'parse-stack'
|
1335
1674
|
```
|
1336
1675
|
|
1337
1676
|
or install it locally
|