Parsistence 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Parsistence.gemspec +23 -0
- data/README.md +124 -0
- data/Rakefile +4 -0
- data/lib/Parsistence/Model.rb +172 -0
- data/lib/Parsistence/Query.rb +223 -0
- data/lib/Parsistence/User.rb +34 -0
- data/lib/Parsistence/version.rb +3 -0
- data/lib/Parsistence.rb +8 -0
- metadata +60 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Parsistence.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/Parsistence/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "Parsistence"
|
6
|
+
s.version = Parsistence::VERSION
|
7
|
+
s.authors = ["Jamon Holmgren", "Silas J. Matson", "Alan deLevie"]
|
8
|
+
s.email = ["jamon@clearsightstudio.com", "silas@clearsightstudio.com", "adelevie@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/clearsightstudio/Parsistence"
|
10
|
+
s.summary = %q{Your models on RubyMotion and Parse in a persistence.js style pattern.}
|
11
|
+
s.description = %q{Your models on RubyMotion and Parse in a persistence.js style pattern.}
|
12
|
+
|
13
|
+
s.rubyforge_project = "Parsistence"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
# specify any dependencies here; for example:
|
21
|
+
# s.add_development_dependency "rspec"
|
22
|
+
# s.add_runtime_dependency "rest-client"
|
23
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# About
|
2
|
+
|
3
|
+
Parsistence provides an Active Record pattern to your Parse models on RubyMotion.
|
4
|
+
It's an early fork from [ParseModel](https://github.com/adelevie/ParseModel) by
|
5
|
+
Alan deLevie but goes a different direction with its implementation.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Create a model:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
class Post
|
13
|
+
include Parsistence::Model
|
14
|
+
|
15
|
+
fields :title, :body, :author
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
Create an instance:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
p = Post.new
|
23
|
+
p.title = "Why RubyMotion Is Better Than Objective-C"
|
24
|
+
p.author = "Josh Symonds"
|
25
|
+
p.body = "trololol"
|
26
|
+
p.saveEventually
|
27
|
+
```
|
28
|
+
|
29
|
+
`Parsistence::Model` objects will `respond_to?` to all methods available to [`PFObject`](https://parse.com/docs/ios/api/Classes/PFObject.html) in the Parse iOS SDK. You can also access the `PFObject` instance directly with, you guessed it, `Parsistence::Model#PFObject`.
|
30
|
+
|
31
|
+
### Users
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
class User
|
35
|
+
include Parsistence::User
|
36
|
+
end
|
37
|
+
|
38
|
+
user = User.new
|
39
|
+
user.username = "adelevie"
|
40
|
+
user.email = "adelevie@gmail.com"
|
41
|
+
user.password = "foobar"
|
42
|
+
user.signUp
|
43
|
+
|
44
|
+
users = User.all
|
45
|
+
users.map {|u| u.objectId}.include?(user.objectId) #=> true
|
46
|
+
```
|
47
|
+
|
48
|
+
`Parsistence::User` delegates to `PFUser` in a very similar fashion as `Parsistence::Model` delegates to `PFOBject`. `Parsistence::User` includes `Parsistence::Model`, in fact.
|
49
|
+
|
50
|
+
### Queries
|
51
|
+
|
52
|
+
Queries use a somewhat different pattern than ActiveRecord but are relatively familiar. They are most like persistence.js.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Car.eq(license: "ABC-123", model: "Camry").order(year: :desc).limit(25).fetch do |cars, error|
|
56
|
+
if cars
|
57
|
+
cars.each do |car|
|
58
|
+
# `car` is an instance of your `Car` model here.
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
Chain multiple conditions together, even the same condition type multiple times, then run `fetch` to execute the query. Pass in a block with two fields to receive the data.
|
65
|
+
|
66
|
+
####Available Conditions
|
67
|
+
(note: each condition can take multiple comma-separated fields and values)
|
68
|
+
|
69
|
+
**eq:** Check if equal the passed in values.
|
70
|
+
|
71
|
+
**notEq:** Check if NOT equal to the passed in values.
|
72
|
+
|
73
|
+
**gt:** Check if greater than the passed in values.
|
74
|
+
|
75
|
+
**lt:** Check if less than the passed in values.
|
76
|
+
|
77
|
+
**gte:** Check if greater or equal to than the passed in values.
|
78
|
+
|
79
|
+
**lte:** Check if less than or equal to the passed in values.
|
80
|
+
|
81
|
+
**order:** Order by one or more fields. Specify :asc or :desc.
|
82
|
+
|
83
|
+
**limit:** Limit is slightly different...it takes either one argument (limit) or two (offset, limit).
|
84
|
+
|
85
|
+
### Relationships
|
86
|
+
|
87
|
+
Define your relationships in the Parse.com dashboard and also in your models.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
class Post
|
91
|
+
include Parsistence::Model
|
92
|
+
|
93
|
+
fields :title, :body, :author
|
94
|
+
|
95
|
+
relations :author
|
96
|
+
end
|
97
|
+
|
98
|
+
Author.where(name: "Jamon Holmgren").fetchOne do |fetchedAuthor, error|
|
99
|
+
p = Post.new
|
100
|
+
p.title = "Awesome Readme"
|
101
|
+
p.body = "Read this first!"
|
102
|
+
p.author = fetchedAuthor
|
103
|
+
p.save
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
|
108
|
+
## Installation
|
109
|
+
|
110
|
+
Either `gem install Parsistence` then `require 'Parsistence'` in your `Rakefile`, OR
|
111
|
+
|
112
|
+
`gem "Parsistence"` in your Gemfile. ([Instructions for Bundler setup with Rubymotion)](http://thunderboltlabs.com/posts/using-bundler-with-rubymotion)
|
113
|
+
|
114
|
+
Somewhere in your code, such as `app/app_delegate.rb` set your API keys:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
Parse.setApplicationId("1234567890", clientKey:"abcdefghijk")
|
118
|
+
```
|
119
|
+
|
120
|
+
To install the Parse iOS SDK in your RubyMotion project, read [this](http://www.rubymotion.com/developer-center/guides/project-management/#_using_3rd_party_libraries) and [this](http://stackoverflow.com/a/10453895/94154).
|
121
|
+
|
122
|
+
## License
|
123
|
+
|
124
|
+
See LICENSE.txt
|
data/Rakefile
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
module Parsistence
|
2
|
+
module Model
|
3
|
+
attr_accessor :PFObject, :errors
|
4
|
+
|
5
|
+
RESERVED_KEYS = [:objectId]
|
6
|
+
|
7
|
+
def initialize(pf=nil)
|
8
|
+
if pf
|
9
|
+
self.PFObject = pf
|
10
|
+
else
|
11
|
+
self.PFObject = PFObject.objectWithClassName(self.class.to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
# setupRelations unless pf
|
15
|
+
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# This code is to correct for a bug where relations aren't initialized when creating a new instance
|
20
|
+
# def setupRelations
|
21
|
+
# relations.each do |r|
|
22
|
+
# self.send("#{r}=", @PFObject.relationforKey(r))
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
|
26
|
+
def method_missing(method, *args, &block)
|
27
|
+
method = method.to_sym
|
28
|
+
if fields.include?(method)
|
29
|
+
return getField(method)
|
30
|
+
elsif relations.include?(method)
|
31
|
+
return getRelation(method)
|
32
|
+
elsif relations.map {|r| "#{r}=".include?(method)}
|
33
|
+
method = method.split("=")[0]
|
34
|
+
return setRelation(method, args.first)
|
35
|
+
elsif @PFObject.respond_to?(method)
|
36
|
+
return @PFObject.send(method, *args, &block)
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def fields
|
43
|
+
self.class.send(:get_fields)
|
44
|
+
end
|
45
|
+
|
46
|
+
def relations
|
47
|
+
self.class.send(:get_relations)
|
48
|
+
end
|
49
|
+
|
50
|
+
def getField(field)
|
51
|
+
field = field.to_sym
|
52
|
+
return @PFObject.send(field) if RESERVED_KEYS.include?(field)
|
53
|
+
return @PFObject[field] if fields.include? field
|
54
|
+
raise "Parsistence Exception: Invalid field name #{field} for object #{self.class.to_s}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def setField(field, value)
|
58
|
+
return @PFObject.send("#{field}=", value) if RESERVED_KEYS.include?(field)
|
59
|
+
return @PFObject[field] = value if fields.include? field.to_sym
|
60
|
+
raise "Parsistence Exception: Invalid field name #{field} for object #{self.class.to_s}" unless fields.include? field.to_sym
|
61
|
+
end
|
62
|
+
|
63
|
+
def getRelation(field)
|
64
|
+
return @PFObject.objectForKey(field) if relations.include? field.to_sym
|
65
|
+
raise "Parsistence Exception: Invalid relation name #{field} for object #{self.class.to_s}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def setRelation(relation, value)
|
69
|
+
value = value.PFObject if value.respond_to? :PFObject # unwrap object
|
70
|
+
# return setRelation(relation, value) # This SHOULD work
|
71
|
+
|
72
|
+
relation = @PFObject.relationforKey(relation)
|
73
|
+
|
74
|
+
return relation.addObject(value) if relations.include? relation.to_sym
|
75
|
+
raise "Parsistence Exception: Invalid relation name #{relation} for object #{self.class.to_s}" unless relations.include? relation.to_sym
|
76
|
+
end
|
77
|
+
|
78
|
+
def attributes
|
79
|
+
attributes = {}
|
80
|
+
fields.each do |f|
|
81
|
+
attributes[f] = getField(f)
|
82
|
+
end
|
83
|
+
@attributes = attributes
|
84
|
+
end
|
85
|
+
|
86
|
+
def attributes=(hashValue)
|
87
|
+
hashValue.each do |k, v|
|
88
|
+
next if v.nil? # Protection
|
89
|
+
setField(k, v) unless k.nil?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def save
|
94
|
+
saved = false
|
95
|
+
unless before_save == false
|
96
|
+
self.attributes.each do |field, value|
|
97
|
+
validateField field, value
|
98
|
+
end
|
99
|
+
|
100
|
+
saved = @PFObject.save
|
101
|
+
after_save if saved
|
102
|
+
end
|
103
|
+
saved
|
104
|
+
end
|
105
|
+
|
106
|
+
def before_save; end
|
107
|
+
def after_save; end
|
108
|
+
|
109
|
+
# Validations
|
110
|
+
def presenceValidations
|
111
|
+
self.class.send(:get_presenceValidations)
|
112
|
+
end
|
113
|
+
|
114
|
+
def validateField(field, value)
|
115
|
+
@errors ||= {}
|
116
|
+
@errors[field] = "#{field} can't be blank" if presenceValidations.include?(field) && value.nil? || value == ""
|
117
|
+
end
|
118
|
+
|
119
|
+
def errorForField(field)
|
120
|
+
@errors[field] || false
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
module ClassMethods
|
125
|
+
def fields(*args)
|
126
|
+
args.each {|arg| field(arg)}
|
127
|
+
end
|
128
|
+
|
129
|
+
def field(name)
|
130
|
+
@fields ||= [:objectId]
|
131
|
+
@fields << name.to_sym
|
132
|
+
@fields.uniq!
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_fields
|
136
|
+
@fields
|
137
|
+
end
|
138
|
+
|
139
|
+
def relations(*args)
|
140
|
+
args.each { |arg| relation(arg)}
|
141
|
+
end
|
142
|
+
|
143
|
+
def relation(name)
|
144
|
+
@relations ||= []
|
145
|
+
@relations << name.to_sym
|
146
|
+
@relations.uniq!
|
147
|
+
end
|
148
|
+
|
149
|
+
def get_relations
|
150
|
+
@relations ||= []
|
151
|
+
end
|
152
|
+
|
153
|
+
def validates_presence_of(*args)
|
154
|
+
args.each {|arg| validate_presence(arg)}
|
155
|
+
end
|
156
|
+
|
157
|
+
def get_presenceValidations
|
158
|
+
@presenceValidations ||= []
|
159
|
+
end
|
160
|
+
|
161
|
+
def validate_presence(field)
|
162
|
+
@presenceValidations ||= []
|
163
|
+
@presenceValidations << field
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.included(base)
|
168
|
+
base.extend(ClassMethods)
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module Parsistence
|
2
|
+
module Model
|
3
|
+
module ClassMethods
|
4
|
+
QUERY_STUBS = [ :fetch, :where, :first, :limit, :order, :eq, :notEq, :lt, :gt, :lte, :gte ] # :limit is different
|
5
|
+
|
6
|
+
def method_missing(method, *args, &block)
|
7
|
+
if method == :limit
|
8
|
+
return self.limit(args.first) if args.length == 1
|
9
|
+
return self.limit(args.first, args.last)
|
10
|
+
elsif QUERY_STUBS.include? method.to_sym
|
11
|
+
q = Parsistence::Query.new
|
12
|
+
q.klass = self
|
13
|
+
return q.send(method, args.first, &block) if block
|
14
|
+
return q.send(method, args.first)
|
15
|
+
elsif method.start_with?("find_by_")
|
16
|
+
attribute = method.gsub("find_by_", "")
|
17
|
+
cond[attribute] = args.first
|
18
|
+
return self.limit(1).where(cond, block)
|
19
|
+
elsif method.start_with?("find_all_by_")
|
20
|
+
# attribute = method.gsub("find_all_by_", "")
|
21
|
+
# cond[attribute] = args.first
|
22
|
+
# return self.where(cond, block)
|
23
|
+
else
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Query
|
30
|
+
attr_accessor :klass
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@conditions = {}
|
34
|
+
@negativeConditions = {}
|
35
|
+
@ltConditions = {}
|
36
|
+
@gtConditions = {}
|
37
|
+
@lteConditions = {}
|
38
|
+
@gteConditions = {}
|
39
|
+
@order = {}
|
40
|
+
@limit = nil
|
41
|
+
@offset = nil
|
42
|
+
@includes = []
|
43
|
+
end
|
44
|
+
|
45
|
+
def createQuery
|
46
|
+
query = PFQuery.queryWithClassName(self.klass.to_s)
|
47
|
+
$stderr.puts @includes
|
48
|
+
@includes.each do |include|
|
49
|
+
query.includeKey(include)
|
50
|
+
end
|
51
|
+
|
52
|
+
@conditions.each do |key, value|
|
53
|
+
value = value.PFObject if value.respond_to? :PFObject
|
54
|
+
query.whereKey(key, equalTo: value)
|
55
|
+
end
|
56
|
+
@negativeConditions.each do |key, value|
|
57
|
+
value = value.PFObject if value.respond_to? :PFObject
|
58
|
+
query.whereKey(key, notEqualTo: value)
|
59
|
+
end
|
60
|
+
@ltConditions.each do |key, value|
|
61
|
+
value = value.PFObject if value.respond_to? :PFObject
|
62
|
+
query.whereKey(key, lessThan: value)
|
63
|
+
end
|
64
|
+
@gtConditions.each do |key, value|
|
65
|
+
value = value.PFObject if value.respond_to? :PFObject
|
66
|
+
query.whereKey(key, greaterThan: value)
|
67
|
+
end
|
68
|
+
@lteConditions.each do |key, value|
|
69
|
+
value = value.PFObject if value.respond_to? :PFObject
|
70
|
+
query.whereKey(key, lessThanOrEqualTo: value)
|
71
|
+
end
|
72
|
+
@gteConditions.each do |key, value|
|
73
|
+
value = value.PFObject if value.respond_to? :PFObject
|
74
|
+
query.whereKey(key, greaterThanOrEqualTo: value)
|
75
|
+
end
|
76
|
+
first = true
|
77
|
+
@order.each do |field, direction|
|
78
|
+
if first
|
79
|
+
# $stderr.puts "Setting order first"
|
80
|
+
query.orderByAscending(field) if direction && direction == :asc
|
81
|
+
query.orderByDescending(field) if direction && direction == :desc
|
82
|
+
first = false
|
83
|
+
else
|
84
|
+
# $stderr.puts "Setting order again"
|
85
|
+
query.addAscendingOrder(field) if direction && direction == :asc
|
86
|
+
query.addDescendingOrder(field) if direction && direction == :desc
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
query.limit = @limit if @limit
|
91
|
+
query.skip = @offset if @offset
|
92
|
+
|
93
|
+
query
|
94
|
+
end
|
95
|
+
|
96
|
+
def fetch(&callback)
|
97
|
+
if @limit && @limit == 1
|
98
|
+
fetchOne(&callback)
|
99
|
+
else
|
100
|
+
fetchAll(&callback)
|
101
|
+
end
|
102
|
+
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
def fetchAll(&callback)
|
107
|
+
query = createQuery
|
108
|
+
|
109
|
+
myKlass = self.klass
|
110
|
+
query.findObjectsInBackgroundWithBlock (lambda { |items, error|
|
111
|
+
modelItems = items.map! { |item| myKlass.new(item) } if items
|
112
|
+
callback.call modelItems, error
|
113
|
+
})
|
114
|
+
end
|
115
|
+
|
116
|
+
def fetchOne(&callback)
|
117
|
+
limit(0, 1)
|
118
|
+
query = createQuery
|
119
|
+
|
120
|
+
myKlass = self.klass
|
121
|
+
query.getFirstObjectInBackgroundWithBlock (lambda { |item, error|
|
122
|
+
modelItem = myKlass.new(item) if item
|
123
|
+
callback.call modelItem, error
|
124
|
+
})
|
125
|
+
end
|
126
|
+
|
127
|
+
# Query methods
|
128
|
+
def where(*conditions, &callback)
|
129
|
+
eq(conditions.first)
|
130
|
+
fetch(&callback)
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
def all(&callback)
|
135
|
+
fetch(&callback)
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
|
139
|
+
def first(&callback)
|
140
|
+
limit(0, 1)
|
141
|
+
fetch(&callback)
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
|
145
|
+
def showQuery
|
146
|
+
$stderr.puts "Conditions: #{@conditions.to_s}"
|
147
|
+
$stderr.puts "negativeConditions: #{@negativeConditions.to_s}"
|
148
|
+
$stderr.puts "ltConditions: #{@ltConditions.to_s}"
|
149
|
+
$stderr.puts "gtConditions: #{@gtConditions.to_s}"
|
150
|
+
$stderr.puts "lteConditions: #{@lteConditions.to_s}"
|
151
|
+
$stderr.puts "gteConditions: #{@gteConditions.to_s}"
|
152
|
+
$stderr.puts "order: #{@order.to_s}"
|
153
|
+
$stderr.puts "limit: #{@limit.to_s}"
|
154
|
+
$stderr.puts "offset: #{@offset.to_s}"
|
155
|
+
end
|
156
|
+
|
157
|
+
# Query parameter methods
|
158
|
+
def limit(offset, number = nil)
|
159
|
+
if number.nil?
|
160
|
+
number = offset
|
161
|
+
offset = 0
|
162
|
+
end
|
163
|
+
@offset = offset
|
164
|
+
@limit = number
|
165
|
+
self
|
166
|
+
end
|
167
|
+
|
168
|
+
def order(*fields)
|
169
|
+
fields.each do |field|
|
170
|
+
@order.merge! field
|
171
|
+
end
|
172
|
+
self
|
173
|
+
end
|
174
|
+
|
175
|
+
def eq(*fields)
|
176
|
+
fields.each do |field|
|
177
|
+
@conditions.merge! field
|
178
|
+
end
|
179
|
+
self
|
180
|
+
end
|
181
|
+
|
182
|
+
def notEq(*fields)
|
183
|
+
fields.each do |field|
|
184
|
+
@negativeConditions.merge! field
|
185
|
+
end
|
186
|
+
self
|
187
|
+
end
|
188
|
+
|
189
|
+
def lt(*fields)
|
190
|
+
fields.each do |field|
|
191
|
+
@ltConditions.merge! field
|
192
|
+
end
|
193
|
+
self
|
194
|
+
end
|
195
|
+
|
196
|
+
def gt(*fields)
|
197
|
+
fields.each do |field|
|
198
|
+
@gtConditions.merge! field
|
199
|
+
end
|
200
|
+
self
|
201
|
+
end
|
202
|
+
|
203
|
+
def lte(*fields)
|
204
|
+
fields.each do |field|
|
205
|
+
@lteConditions.merge! field
|
206
|
+
end
|
207
|
+
self
|
208
|
+
end
|
209
|
+
|
210
|
+
def gte(*fields)
|
211
|
+
fields.each do |field|
|
212
|
+
@gteConditions.merge! field
|
213
|
+
end
|
214
|
+
self
|
215
|
+
end
|
216
|
+
|
217
|
+
def includes(*fields)
|
218
|
+
fields.each do |field|
|
219
|
+
@includes << field
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Parsistence
|
2
|
+
module User
|
3
|
+
include ::Parsistence::Model
|
4
|
+
|
5
|
+
attr_accessor :PFUser
|
6
|
+
|
7
|
+
RESERVED_KEYS = [:objectId, :username, :password, :email]
|
8
|
+
|
9
|
+
def PFObject=(value)
|
10
|
+
@PFObject = value
|
11
|
+
@PFUser = @PFObject
|
12
|
+
end
|
13
|
+
|
14
|
+
def PFUser=(value)
|
15
|
+
self.PFObject = value
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def all
|
20
|
+
query = PFQuery.queryForUser
|
21
|
+
users = query.findObjects
|
22
|
+
users
|
23
|
+
end
|
24
|
+
|
25
|
+
def currentUser
|
26
|
+
PFUser.currentUser
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.included(base)
|
31
|
+
base.extend(ClassMethods)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/Parsistence.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require "Parsistence/version"
|
2
|
+
|
3
|
+
Motion::Project::App.setup do |app|
|
4
|
+
Dir.glob(File.join(File.dirname(__FILE__), "Parsistence/*.rb")).each do |file|
|
5
|
+
app.files.unshift(file) unless file.include? "Model.rb"
|
6
|
+
end
|
7
|
+
app.files.unshift(File.join(File.dirname(__FILE__), "Parsistence/Model.rb"))
|
8
|
+
end
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Parsistence
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jamon Holmgren
|
9
|
+
- Silas J. Matson
|
10
|
+
- Alan deLevie
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-09-05 00:00:00.000000000 Z
|
15
|
+
dependencies: []
|
16
|
+
description: Your models on RubyMotion and Parse in a persistence.js style pattern.
|
17
|
+
email:
|
18
|
+
- jamon@clearsightstudio.com
|
19
|
+
- silas@clearsightstudio.com
|
20
|
+
- adelevie@gmail.com
|
21
|
+
executables: []
|
22
|
+
extensions: []
|
23
|
+
extra_rdoc_files: []
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- Gemfile
|
27
|
+
- Parsistence.gemspec
|
28
|
+
- README.md
|
29
|
+
- Rakefile
|
30
|
+
- lib/Parsistence.rb
|
31
|
+
- lib/Parsistence/Model.rb
|
32
|
+
- lib/Parsistence/Query.rb
|
33
|
+
- lib/Parsistence/User.rb
|
34
|
+
- lib/Parsistence/version.rb
|
35
|
+
homepage: https://github.com/clearsightstudio/Parsistence
|
36
|
+
licenses: []
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubyforge_project: Parsistence
|
55
|
+
rubygems_version: 1.8.22
|
56
|
+
signing_key:
|
57
|
+
specification_version: 3
|
58
|
+
summary: Your models on RubyMotion and Parse in a persistence.js style pattern.
|
59
|
+
test_files: []
|
60
|
+
has_rdoc:
|