Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/technohippy/parsecom
yet another parse.com library for ruby
https://github.com/technohippy/parsecom
Last synced: 4 months ago
JSON representation
yet another parse.com library for ruby
- Host: GitHub
- URL: https://github.com/technohippy/parsecom
- Owner: technohippy
- License: mit
- Created: 2013-09-30T14:39:17.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2014-12-17T08:00:40.000Z (about 10 years ago)
- Last Synced: 2024-10-06T11:06:18.405Z (4 months ago)
- Language: Ruby
- Homepage:
- Size: 508 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Parsecom
Yet-Another Parse.com Library written in Pure Ruby
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [Parsecom](#parsecom)
- [Usage](#usage)
- [Preparing](#preparing)
- [Declaring Parse Classes](#declaring-parse-classes)
- [Objects](#objects)
- [Creating Objects](#creating-objects)
- [Retrieving Objects](#retrieving-objects)
- [Updating Objects](#updating-objects)
- [Counters](#counters)
- [Arrays](#arrays)
- [Relations](#relations)
- [Deleting Objects](#deleting-objects)
- [Batch Operations](#batch-operations)
- [Queries](#queries)
- [Basic Queries](#basic-queries)
- [Query Constraints](#query-constraints)
- [Queries on Array Values](#queries-on-array-values)
- [Relational Queries](#relational-queries)
- [Counting Objects](#counting-objects)
- [Compound Queries](#compound-queries)
- [Users](#users)
- [Sign up](#sign-up)
- [Log in](#log-in)
- [Requesting A Password Reset](#requesting-a-password-reset)
- [Retrieving Users](#retrieving-users)
- [Updating Users](#updating-users)
- [Querying](#querying)
- [Deleting Users](#deleting-users)
- [Linking Users](#linking-users)
- [Roles](#roles)
- [Creating Roles](#creating-roles)
- [Retrieving Roles](#retrieving-roles)
- [Updating Roles](#updating-roles)
- [Deleting Roles](#deleting-roles)
- [Files](#files)
- [Uploading Files](#uploading-files)
- [Associating with Objects](#associating-with-objects)
- [Deleting Files](#deleting-files)
- [Analytics](#analytics)
- [App-Open Analytics](#app-open-analytics)
- [Custom Analytics](#custom-analytics)
- [Installations](#installations)
- [Uploading Installation Data](#uploading-installation-data)
- [Retrieving Installations](#retrieving-installations)
- [Updating Installations](#updating-installations)
- [Querying Installations](#querying-installations)
- [Deleting Installations](#deleting-installations)
- [Cloud Functions](#cloud-functions)
- [GeoPoints](#geopoints)
- [GeoPoint](#geopoint)
- [Geo Queries](#geo-queries)
- [Security](#security)
- [Debug](#debug)## Usage
### Preparing
Before using the library, you should import this and set your credentials on
the library.```ruby
require 'parsecom'
Parse.credentials :application_id => 'YOUR APPID', :api_key => 'YOUR APIKEY'
```If you have some plan to use the master_key, please set it.
```ruby
Parse.credentials :application_id => 'YOUR APPID', :api_key => 'YOUR APIKEY',
:master_key => 'YOUR MASTER KEY'
```If you do not want to write your credentials on your code directly,
please set environment variables:export PARSE_APPLICATION_ID=""
export PARSE_API_KEY=""
export PARSE_MASTER_KEY=""### Declaring Parse Classes
There are three ways to declare a parse class.
First, you can declare a ruby class inherited from Parse::Object. By using
this way, you can add your own properties and methods to the class.```ruby
class GameScore < Parse::Object
# ..snip..
end
```Secondly, you can also declare your parse class by calling the Parse::Object
method.```ruby
Parse::Object(:GameScore)
```It returns a parse class, so that you can call its class methods directly.
```ruby
Parse::Object(:GameScore).find :limit => 3
```Lastly, Parse::Object class provides create method for you to declare new
class.```ruby
Parse::Object.create :GameScore
```It may be suitable for writing code in declarative style.
### Objects
#### Creating Objects
To create new parse object, just new and save the object.
```ruby
game_score = GameScore.new
game_score.score = 1337
game_score.playerName = 'Sean Plott'
game_score.cheatMode = false
game_score.new? # => true
game_score.save
game_score.new? # => false
game_score.parse_object_id # => 'Ed1nuqPvcm'
```#### Retrieving Objects
There are two ways to retrieve objects. One is using Query objects directly and
another is using Parse::Object as a facade of a query object.```ruby
# useing Query object directly
query = Parse::Query.new GameScore
query.where :objectId => 'Ed1nuqPvcm'
results = query.run# using Query object through Parse::Object
results = GameScore.find :where => {:objectId => 'Ed1nuqPvcm'}
# if you would like to find by objectId, you can easily pass it directly
result = GameScore.find_by_id 'Ed1nuqPvcm'
```To fetch a child object, you can use the :include parameter.
```ruby
results = GameScore.find :where => {:objectId => 'Ed1nuqPvcm'}, :include => 'game'
```To know more about retrieving objects, see spec/parse_query_spec.rb
#### Updating Objects
To update attributes, just update the attribute and save.
```ruby
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
game_score.score = 73453
game_score.save
```If you want to update attributes without retrieving the object, you can use
the Parse::Client object for it.```ruby
Parse::Client.default.update :GaemScore, 'Ed1nuqPvcm', :score => 73453
```##### Counters
```ruby
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
game_score.score = Parse::Op::Increment.new 1
game_score.save
```##### Arrays
```ruby
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
game_score.skils = Parse::Op::AddUnique.new 'flying', 'kungfu'
game_score.save
```##### Relations
```ruby
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
game_score.opponents = Parse::Op::AddRelation.new player.pointer
game_score.save
``````ruby
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
game_score.opponents = Parse::Op::RemoveRelation.new player.pointer
game_score.save
```#### Deleting Objects
```ruby
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
game_score.delete
``````ruby
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
game_score.opponents = Parse::Op::Delete.new
game_score.save
```#### Batch Operations
```ruby
seans_score = GameScore.new 'score' => 1337, 'playerName' => 'Sean Plott'
zerocools_score = GameScore.new 'score' => 1338, 'playerName' => 'ZeroCool'
batch = Parse::Batch.new
batch.add_request do
seans_score.save
zerocools_score.save
end
result = batch.run
```Or
```ruby
seans_score = GameScore.new 'score' => 1337, 'playerName' => 'Sean Plott'
zerocools_score = GameScore.new 'score' => 1338, 'playerName' => 'ZeroCool'
Parse.batch do
seans_score.save
zerocools_score.save
end
```### Queries
#### Basic Queries
```ruby
game_scores = GameScore.find :all
```#### Query Constraints
```ruby
game_scores = GameScore.find :where => {"playerName" => "Sean Plott", "cheatMode" => false}
``````ruby
game_scores = GameScore.find :where => proc {
column(:score).gte(1000).lte(3000)
}
``````ruby
game_scores = GameScore.find :where => proc {
column(:score).between(1000..3000)
}
``````ruby
game_scores = GameScore.find :where => proc {
column(:score).in(1, 3, 5, 7, 9)
}
``````ruby
game_scores = GameScore.find :where => proc {
column(:playerName).nin("Jonathan Walsh", "Dario Wunsch", "Shawn Simon")
}
``````ruby
game_scores = GameScore.find :where => proc {
column(:score).exists
}
``````ruby
game_scores = GameScore.find :where => proc {
column(:score).exists(false)
}
``````ruby
game_scores = GameScore.find :where => proc {
subquery = subquery_for :Team
subquery.where {column(:winPct).gt(0.5)}
subquery.key = 'city'
column(:hometown).select(subquery)
}
``````ruby
game_scores = GameScore.find :order => 'score'
``````ruby
game_scores = GameScore.find :order => '-score'
game_scores = GameScore.find :order_desc => 'score'
``````ruby
game_scores = GameScore.find :order => ['score', '-name']
``````ruby
game_scores = GameScore.find :limit => 200, :skip => 400
``````ruby
game_scores = GameScore.find :keys => ['score', 'playerName']
```#### Queries on Array Values
```ruby
game_scores = GameScore.find :where => proc {
column(:arrayKey).contains(2)
}
``````ruby
game_scores = GameScore.find :where => proc {
column(:arrayKey).all(2, 3, 4)
}
```#### Relational Queries
```ruby
game_scores = GameScore.find :where => proc {
post = Parse::Object(:Post).new :objectId => '8TOXdXf3tz'
column(:post).eq(post)
}
``````ruby
game_scores = GameScore.find :where => proc {
subquery = subquery_for :Post
subquery.where do
column(:image).exists(true)
end
column(:post).in_query(subquery)
}
``````ruby
game_scores = GameScore.find :where => proc {
pointer = Parse::Pointer.new('className' => 'Post', 'objectId' => '8TOXdXf3tz')
related_to :likes, pointer
}
```#### Counting Objects
```ruby
game_score_count = GameScore.count 'playerName' => 'Jonathan Walsh'
```#### Compound Queries
```ruby
game_scores = GameScore.find :where => proc {
or_condition column(:wins).gt(150), column(:wins).lt(5)
}
```### Users
#### Sign up
```ruby
user = Parse::User.sign_up 'YOUR USERNAME', 'YOUR PASSWORD'
```#### Log in
```ruby
user = Parse::User.log_in 'YOUR USERNAME', 'YOUR PASSWORD'
```#### Requesting A Password Reset
```ruby
Parse::User.request_password_reset '[email protected]'
```#### Retrieving Users
```ruby
user = Parse::User.find_by_id :g7y9tkhB7O
```#### Updating Users
```ruby
user = Parse::User.find_by_id :g7y9tkhB7O
user.phone = '415-369-6201'
user.save
```#### Querying
```ruby
users = Parse::User.find :all
```#### Deleting Users
```ruby
user = Parse::User.find_by_id :g7y9tkhB7O
user.delete
```#### Linking Users
TBD
### Roles
#### Creating Roles
```ruby
moderator = Parse::Role.new 'name' => 'Moderators', 'ACL' => Parse::ACL::PUBLIC_READ_ONLY
moderator.save
``````ruby
moderator = Parse::Role.new 'name' => 'Moderators', 'ACL' => Parse::ACL::PUBLIC_READ_ONLY
moderator.roles.add Parse::Role.new('objectId' => 'Ed1nuqPvc')
moderator.users.add Parse::User.new('objectId' => '8TOXdXf3tz')
moderator.save
```#### Retrieving Roles
```ruby
role = Parse::Role.find_by_id 'mrmBZvsErB'
role.name # => 'Moderators'
role.ACL.readable? '*' # => true
role.ACL.writable? 'role:Administrators' # => true
```#### Updating Roles
```ruby
user1 = Parse::User.new 'objectId' => '8TOXdXf3tz'
user2 = Parse::User.new 'objectId' => 'g7y9tkhB7O'
role = Parse::Role.find_by_id 'mrmBZvsErB'
role.users = Parse::Op::AddRelation.new user1.pointer, user2.pointer
role.save
``````ruby
removed_role = Parse::Role.new 'objectId' => 'Ed1nuqPvc'
role = Parse::Role.find_by_id 'mrmBZvsErB'
role.roles = Parse::Op::RemoveRelation.new removed_role.pointer
role.save
```#### Deleting Roles
```ruby
role = Parse::Role.find_by_id 'mrmBZvsErB'
role.delete
```### Files
#### Uploading Files
```ruby
file = Parse::ParseFile.new :name => 'hello.txt', :content => 'Hello, World!'
file.save
file.url # => "http://files.parse.com/7883...223/7480...b6d-hello.txt"
``````ruby
file = Parse::ParseFile.new :name => 'myPicture.jpg', :content => './myPicture.jpg'
file.save
file.url # => "http://files.parse.com/7883...223/81c7...bdf-myPicture.jpg"
```#### Associating with Objects
```ruby
file = Parse::ParseFile.new :name => 'profile.png', :content => './profile.png'
profile = PlayerProfile.new 'name' => 'Andrew', 'picture' => file
profile.save
```#### Deleting Files
```ruby
file.delete!
```### Analytics
#### App-Open Analytics
```ruby
app_opened_event = Parse::Event::AppOpened.new :at => '2013-10-18T20:53:25Z'
app_opened_event.fire
``````ruby
Parse::Event::AppOpened.fire :at => '2013-10-18T20:53:25Z'
```#### Custom Analytics
```ruby
Parse::Event.create :Search
search_event = Search.new :at => '2013-10-18T20:53:25Z',
:priceRange => "1000-1500", :source => "craigslist", :dayType => "weekday"
search_event.fire
``````ruby
error_event = Parse::Event::Error.new :at => '2013-10-18T20:53:25Z', :code => 404
error_event.fire
```### Push Notifications
TBD
### Installations
#### Uploading Installation Data
```ruby
installation = Parse::Installation.new :deviceType => 'ios', :deviceToken => '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', :channels => ['']
installation.save
```#### Retrieving Installations
```ruby
installation = Parse::Installation.find_by_id :mrmBZvsErB
```#### Updating Installations
```ruby
installation = Parse::Installation.find_by_id :mrmBZvsErB
installation.channels = ['', 'foo']
installation.save
```#### Querying Installations
```ruby
installations = Parse::Installation.find! :all
```#### Deleting Installations
```ruby
installation = Parse::Installation.find_by_id :mrmBZvsErB
installation.delete!
```### Cloud Functions
```ruby
client = Parse::Client.new
client.hello
```### GeoPoints
#### GeoPoint
```ruby
geo_point = Parse::GeoPoint.new :latitude => 40.0, :longitude => -30.0
place = PlaceObject.new :location => geo_point
```#### Geo Queries
```ruby
place = PlaceObject.find :limit => 10, :where => proc {
geo_point = Parse::GeoPoint.new :latitude => 30.0, :longitude => -20.0
column(:location).near_sphere geop_point
}
``````ruby
places = PlaceObject.find :limit => 10, :where => proc {
geo_point = Parse::GeoPoint.new :latitude => 30.0, :longitude => -20.0
column(:location).near_sphere(geo_point).max_distance_in_miles(10.0)
}
``````ruby
places = PizzaPlaceObject.find :limit => 10, :where => proc {
southwest = Parse::GeoPoint.new :latitude => 37.71, :longitude => -122.53
northeast = Parse::GeoPoint.new :latitude => 30.82, :longitude => -122.37
column(:location).within(southwest, northeast)
}
```### Security
If you add an exclamation mark, "!" after the method name, the method is executed by using the master key.
```ruby
class_a = ClassA.new :columnA => 'Hello, parse.com'
class_a.save!
```If you want to use the master key for all API calls, set the use_master_key flag true so that you don't need to add "!" for all methods.
```ruby
Parse.use_master_key!
```### Debug
To see debug output, set $DEBUG true.
```ruby
$DEBUG = true
Post.find :all
```You can see something like the following in $stderr.
```
opening connection to api.parse.com...
opened
<- "GET /1/classes/Post? HTTP/1.1\r\nX-Parse-Application-Id: abcdefghijklmnopqrstuvwxyz0123456789ABCD\r\nContent-Type: application/json\r\nAccept: application/json\r\nUser-Agent: A parse.com client for ruby\r\nX-Parse-Rest-Api-Key: abcdefghijklmnopqrstuvwxyz0123456789ABCD\r\nHost: api.parse.com\r\n\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "Access-Control-Allow-Origin: *\r\n"
-> "Access-Control-Request-Method: *\r\n"
-> "Cache-Control: max-age=0, private, must-revalidate\r\n"
-> "Content-Type: application/json; charset=utf-8\r\n"
-> "Date: Sun, 08 Dec 2013 08:14:40 GMT\r\n"
-> "ETag: \"abcdefghijklmnopqrstuvwxyz012345\"\r\n"
-> "Server: nginx/1.4.2\r\n"
-> "Set-Cookie: _parse_session=abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789; domain=.parse.com; path=/; expires=Tue, 07-Jan-2014 08:14:40 GMT; secure; HttpOnly\r\n"
-> "Status: 200 OK\r\n"
-> "X-Runtime: 0.116322\r\n"
-> "X-UA-Compatible: IE=Edge,chrome=1\r\n"
-> "Content-Length: 603\r\n"
-> "Connection: keep-alive\r\n"
-> "\r\n"
reading 603 bytes...
-> "{\"results\":[{\"author\":{\"__type\":\"Pointer\",\"className\":\"_User\",\"objectId\":\"xWJVfYPbBP\"},\"body\":\"\xE6\x9C\xAC\xE6\x96\x87\",\"title\":\"\xE3\x82\xBF\xE3\x82\xA4\xE3\x83\x88
\xE3\x83\xAB\",\"comments\":{\"__type\":\"Relation\",\"className\":\"Comment\"},\"createdAt\":\"2013-10-29T15:06:45.872Z\",\"updatedAt\":\"2013-10-29T15:09:01.111Z\",\"objectId\":\"6EyX2aypgD\"
},{\"comments\":{\"__type\":\"Relation\",\"className\":\"Comment\"},\"createdAt\":\"2013-10-30T04:38:47.068Z\",\"updatedAt\":\"2013-10-30T04:38:47.068Z\",\"objectId\":\"njvHr4aelZ\"},{\"comment
s\":{\"__type\":\"Relation\",\"className\":\"Comment\"},\"createdAt\":\"2013-10-30T04:40:37.397Z\",\"updatedAt\":\"2013-10-30T04:40:37.397Z\",\"objectId\":\"EDdGtur3vY\"}]}"
read 603 bytes
Conn keep-alive
```Also you can do dry-run.
```ruby
Parse.dry_run!
Post.find :all
```This does not call any API and shows something like the following in $stderr.
```
get /1/classes/Post?
X-Parse-Application-Id: abcdefghijklmnopqrstuvwxyz0123456789ABCD
Content-Type: application/json
Accept: application/json
User-Agent: A parse.com client for ruby
X-Parse-REST-API-Key: abcdefghijklmnopqrstuvwxyz0123456789ABCD```