cdq 0.1.2 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/LICENSE +21 -0
- data/README.md +206 -58
- data/lib/cdq/cli.rb +1 -13
- data/lib/cdq/version.rb +1 -1
- data/motion/cdq.rb +38 -3
- data/motion/cdq/context.rb +5 -0
- data/motion/cdq/partial_predicate.rb +64 -21
- data/motion/cdq/query.rb +69 -15
- data/motion/cdq/targeted_query.rb +0 -2
- data/templates/model/spec/models/name.rb +1 -1
- metadata +12 -53
- data/.gitignore +0 -12
- data/.travis.yml +0 -2
- data/Gemfile +0 -7
- data/Gemfile.lock +0 -32
- data/Rakefile +0 -28
- data/app/app_delegate.rb +0 -13
- data/app/test_models.rb +0 -15
- data/cdq.gemspec +0 -20
- data/resources/CDQ.xcdatamodeld/.xccurrentversion +0 -8
- data/resources/CDQ.xcdatamodeld/0.0.1.xcdatamodel/contents +0 -34
- data/resources/Default-568h@2x.png +0 -0
- data/resources/KEEPME +0 -0
- data/schemas/001_baseline.rb +0 -44
- data/spec/cdq/collection_proxy_spec.rb +0 -51
- data/spec/cdq/config_spec.rb +0 -74
- data/spec/cdq/context_spec.rb +0 -92
- data/spec/cdq/managed_object_spec.rb +0 -81
- data/spec/cdq/model_spec.rb +0 -14
- data/spec/cdq/module_spec.rb +0 -44
- data/spec/cdq/object_proxy_spec.rb +0 -37
- data/spec/cdq/object_spec.rb +0 -58
- data/spec/cdq/partial_predicate_spec.rb +0 -52
- data/spec/cdq/query_spec.rb +0 -127
- data/spec/cdq/relationship_query_spec.rb +0 -75
- data/spec/cdq/store_spec.rb +0 -39
- data/spec/cdq/targeted_query_spec.rb +0 -120
- data/spec/helpers/thread_helper.rb +0 -16
- data/spec/integration_spec.rb +0 -38
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NzEwODIzMjYzYjBlY2YzYzVjODMzOGFmYjgzZTdhNDA4ZjQzZjJlMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzM1MDIxYmMzZDIxNzY4ZWFmOGQzYjZhOWQ2MjM0NjA3NDQ1Njg4MQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Y2JhZGRhYjRiYzRmNTlhZTJmZjA1ZmViNzdjOTU1YWI2OTgxNDY1MjNlNDg1
|
10
|
+
NTIzYWE3NGU2MTBmZmY1NWI2OTA2MDllNGZiNzQwMzlkMjE0MTcxYTRmZmUz
|
11
|
+
NTEwOGUxODdjMTM3NGFiZmU5YzcxNDRlYjVmMzJlYzUwZGZmYmY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZDI1M2Y3M2RmNzNiY2Q2NjQwYjY1OGU5OGJkMTUxZTI5MmE3YjRjMTIwOTU4
|
14
|
+
YzBiYzBkY2I2Zjc2MWJiNTdkYWI4MzY1ZjJlMmE4ODk2YjQ3ZDAxYzkyZmYy
|
15
|
+
MzY4ZGVkYmM5ZGQzZmE1NTE4OWI0YTFhZDg0OGI2ZTIzYWNjY2I=
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 InfiniteRed LLC (http://infinitered.com)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -4,8 +4,12 @@
|
|
4
4
|
Core Data Query (CDQ) is a library to help you manage your Core Data stack
|
5
5
|
while using RubyMotion. It uses a data model file, which you can generate in
|
6
6
|
XCode, or you can use [ruby-xcdm](https://github.com/infinitered/ruby-xcdm).
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
[![Dependency Status](https://gemnasium.com/infinitered/cdq.png)](https://gemnasium.com/infinitered/cdq)
|
9
|
+
[![Build Status](https://travis-ci.org/infinitered/cdq.png?branch=master)](https://travis-ci.org/infinitered/cdq)
|
10
|
+
[![Gem Version](https://badge.fury.io/rb/cdq.png)](http://badge.fury.io/rb/cdq)
|
11
|
+
|
12
|
+
## Introduction
|
9
13
|
|
10
14
|
CDQ began its life as a fork of
|
11
15
|
[MotionData](https://github.com/alloy/MotionData), but it became obvious I
|
@@ -14,9 +18,10 @@ rewriting almost everything. If you pay attention, you can still find the
|
|
14
18
|
genetic traces, so thanks to @alloy for sharing his work and letting me learn
|
15
19
|
so much.
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
CDQ aims to streamline the process of getting you up and running Core Data, while
|
22
|
+
avoiding too much abstraction or method pollution on top of the SDK. While it
|
23
|
+
borrows many ideas from ActiveRecord (especially AREL), it is designed to
|
24
|
+
harmonize with Core Data's way of doing things first.
|
20
25
|
|
21
26
|
### Why use a static Data Model?
|
22
27
|
|
@@ -26,7 +31,16 @@ schema as it grows, if you can follow a few [simple rules](https://developer.app
|
|
26
31
|
|
27
32
|
## Installing
|
28
33
|
|
29
|
-
|
34
|
+
### Quick Start:
|
35
|
+
|
36
|
+
For brand-new apps, or just to try it out, check out the
|
37
|
+
[Greenfield Quick Start](https://github.com/infinitered/cdq/wiki/Greenfield-Quick-Start) tutorial.
|
38
|
+
There's also a
|
39
|
+
[Cheat Sheet](https://github.com/infinitered/cdq/wiki/CDQ-Cheat-Sheet)
|
40
|
+
and
|
41
|
+
[API docs](http://rubydoc.info/github/infinitered/cdq).
|
42
|
+
|
43
|
+
### Even Quicker Start:
|
30
44
|
|
31
45
|
```bash
|
32
46
|
$ gem install cdq
|
@@ -37,7 +51,7 @@ $ cdq init
|
|
37
51
|
|
38
52
|
This way assumes you want to use ruby-xcdm. Run ```cdq -h``` for list of more generators.
|
39
53
|
|
40
|
-
|
54
|
+
### Using Bundler:
|
41
55
|
|
42
56
|
```ruby
|
43
57
|
gem 'cdq'
|
@@ -56,7 +70,7 @@ it to your resources file and make sure it's named the same as your RubyMotion
|
|
56
70
|
project. If you're using `ruby-xcdm` (which I highly recommend) then it will
|
57
71
|
create the datamodel file automatically and put it in the right place.
|
58
72
|
|
59
|
-
Now include the setup code in your
|
73
|
+
Now include the setup code in your ```app_delegate.rb``` file:
|
60
74
|
|
61
75
|
```ruby
|
62
76
|
class AppDelegate
|
@@ -73,19 +87,102 @@ That's it! You can create specific implementation classes for your entities if
|
|
73
87
|
you want, but it's not required. You can start running queries on the console or
|
74
88
|
in your code right away.
|
75
89
|
|
76
|
-
##
|
90
|
+
## Schema
|
91
|
+
|
92
|
+
The best way to use CDQ is together with ruby-xcdm, which is installed as a
|
93
|
+
dependency. For the full docs, see its [github page](http://github.com/infinitered/ruby-xcdm),
|
94
|
+
but here's a taste. Schema files are found in the "schemas" directory within your
|
95
|
+
app root, and they are versioned for automatic migrations, and this is what they look like:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
schema "0001 initial" do
|
99
|
+
|
100
|
+
entity "Article" do
|
101
|
+
|
102
|
+
string :body, optional: false
|
103
|
+
integer32 :length
|
104
|
+
boolean :published, default: false
|
105
|
+
datetime :publishedAt, default: false
|
106
|
+
string :title, optional: false
|
107
|
+
|
108
|
+
belongs_to :author
|
109
|
+
end
|
110
|
+
|
111
|
+
entity "Author" do
|
112
|
+
float :fee
|
113
|
+
string :name, optional: false
|
114
|
+
has_many :articles
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
Ruby-xcdm translates these files straight into the XML format that Xcode uses for datamodels.
|
121
|
+
|
122
|
+
## Context Management
|
123
|
+
|
124
|
+
Managing NSManagedObjectContext objects in Core Data can be tricky, especially
|
125
|
+
if you are trying to take advantage of nested contexts for better threading
|
126
|
+
behavior. One of the best parts of CDQ is that it handles contexts for you
|
127
|
+
relatively seamlessly. If you have a simple app, you may never need to worry
|
128
|
+
about contexts at all.
|
129
|
+
|
130
|
+
### Nested Contexts
|
131
|
+
|
132
|
+
For a great discussion of why you might want to use nested contexts, see [here](http://www.cocoanetics.com/2012/07/multi-context-coredata/).
|
77
133
|
|
78
|
-
CDQ maintains a stack of
|
79
|
-
operations
|
80
|
-
|
81
|
-
|
134
|
+
CDQ maintains a stack of contexts (one stack per thread), and by default, all
|
135
|
+
operations on objects use the topmost context. You just call ```cdq.save```
|
136
|
+
and it saves the whole stack. Or you can get a list of all the contexts in
|
137
|
+
order with ```cdq.contexts.all``` and do more precise work.
|
138
|
+
|
139
|
+
Settings things up the way you want is easy. Here's how you'd set it up for asynchronous
|
140
|
+
saves:
|
82
141
|
|
83
142
|
```ruby
|
84
|
-
cdq
|
85
|
-
cdq
|
86
|
-
|
87
|
-
|
143
|
+
cdq.contexts.new(NSPrivateQueueConcurrencyType)
|
144
|
+
cdq.contexts.new(NSMainQueueConcurrencyType)
|
145
|
+
```
|
146
|
+
|
147
|
+
This pushes a private queue context onto the bottom of the stack, then a main queue context on top of it.
|
148
|
+
Since the main queue is on top, all your data operations will use that. ```cdq.save``` then saves the
|
149
|
+
main context, and schedules a save on the root context.
|
150
|
+
|
151
|
+
### Temporary Contexts
|
152
|
+
|
153
|
+
From time to time, you may need to use a temporary context. For example, on
|
154
|
+
importing a large amount of data from the network, it's best to process and
|
155
|
+
load into a temporary context (possibly in a background thread) and then move
|
156
|
+
all the data over to your main context all at once. CDQ makes that easy too:
|
88
157
|
|
158
|
+
```ruby
|
159
|
+
cdq.contexts.new(NSConfinementConcurrencyType) do
|
160
|
+
# Your work here
|
161
|
+
end
|
162
|
+
```
|
163
|
+
|
164
|
+
## Object Lifecycle
|
165
|
+
|
166
|
+
### Creating
|
167
|
+
```ruby
|
168
|
+
Author.create(name: "Le Guin", publish_count: 150, first_published: 1970)
|
169
|
+
Author.create(name: "Shakespeare", publish_count: 400, first_published: 1550)
|
170
|
+
Author.create(name: "Blake", publish_count: 100, first_published: 1778)
|
171
|
+
cdq.save
|
172
|
+
```
|
173
|
+
|
174
|
+
### Updating
|
175
|
+
```ruby
|
176
|
+
author = Author.first
|
177
|
+
author.name = "Ursula K. Le Guin"
|
178
|
+
cdq.save
|
179
|
+
```
|
180
|
+
|
181
|
+
### Deleting
|
182
|
+
```ruby
|
183
|
+
author = Author.first
|
184
|
+
author.destroy
|
185
|
+
cdq.save
|
89
186
|
```
|
90
187
|
|
91
188
|
## Queries
|
@@ -100,71 +197,86 @@ running queries that only return a single object, consider rearchitecting.
|
|
100
197
|
That said, queries are sometimes the only solution, and it's very handy to be
|
101
198
|
able to use them easily when debugging from the console, or in unit tests.
|
102
199
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
# Simple Queries
|
107
|
-
cdq('Author').where(:name).eq('Shakespeare')
|
108
|
-
cdq('Author').where(:publish_count).gt(10)
|
200
|
+
All of these queries are infinitely daisy-chainable, and almost everything is
|
201
|
+
possible to do using only chained methods, no need to drop into NSPredicate format
|
202
|
+
strings unless you want to.
|
109
203
|
|
110
|
-
|
111
|
-
|
204
|
+
Here are some examples. See the [cheat
|
205
|
+
sheet](https://github.com/infinitered/cdq/wiki/CDQ-Cheat-Sheet) for a complete
|
206
|
+
list.
|
112
207
|
|
113
|
-
|
114
|
-
cdq('Author').where(:name).eq('Blake').and(:first_published).le(Time.local(1700))
|
208
|
+
### Conditions
|
115
209
|
|
116
|
-
|
117
|
-
|
210
|
+
```ruby
|
211
|
+
Author.where(:name).eq('Shakespeare')
|
212
|
+
Author.where(:publish_count).gt(10)
|
213
|
+
Author.where(name: 'Shakespeare', publish_count: 15)
|
214
|
+
Author.where("name LIKE '%@'", '%kesp%')
|
118
215
|
```
|
119
216
|
|
120
|
-
|
217
|
+
### Sorts, Limits and Offsets
|
121
218
|
|
122
|
-
|
123
|
-
|
219
|
+
```ruby
|
220
|
+
Author.sort_by(:created_at).limit(1).offset(10)
|
221
|
+
Author.sort_by(:created_at, :descending)
|
222
|
+
```
|
223
|
+
|
224
|
+
### Conjunctions
|
124
225
|
|
125
226
|
```ruby
|
126
|
-
|
127
|
-
cdq('Author').scope :prolific, cdq(:publish_count).gt(99)
|
227
|
+
Author.where(:name).eq('Blake').and(:first_published).le(Time.local(1700))
|
128
228
|
|
129
|
-
|
229
|
+
# Multiple comparisons against the same attribute
|
230
|
+
Author.where(:created_at).ge(yesterday).and.lt(today)
|
130
231
|
```
|
131
232
|
|
132
|
-
|
133
|
-
|
134
|
-
|
233
|
+
#### Nested Conjunctions
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
Author.where(:name).contains("Emily").and(cdq(:pub_count).gt(100).or.lt(10))
|
237
|
+
```
|
238
|
+
|
239
|
+
### Fetching
|
240
|
+
|
241
|
+
Like ActiveRecord, CDQ will not run a fetch until you actually request specific
|
242
|
+
objects. There are several methods for getting at the data:
|
243
|
+
|
244
|
+
* ```array```
|
245
|
+
* ```first```
|
246
|
+
* ```each```
|
247
|
+
* ```[]```
|
248
|
+
* ```map```
|
249
|
+
* Anything else in ```Enumerable```
|
135
250
|
|
136
251
|
## Dedicated Models
|
137
252
|
|
138
253
|
If you're using CDQ in a brand new project, you'll probably want to use
|
139
|
-
dedicated model classes for your entities.
|
140
|
-
class-level customization of your model objects, and also a somewhat more
|
254
|
+
dedicated model classes for your entities.
|
141
255
|
familiar-looking and natural syntax for queries and scopes:
|
142
256
|
|
143
257
|
```ruby
|
144
|
-
class Author < CDQManagedOjbect
|
145
|
-
|
146
|
-
scope :prolific, cdq(:publish_count).gt(99)
|
147
|
-
end
|
258
|
+
class Author < CDQManagedOjbect
|
259
|
+
end
|
148
260
|
```
|
149
261
|
|
150
|
-
|
262
|
+
## Named Scopes
|
263
|
+
|
264
|
+
You can save up partially-constructed queries for later use using named scopes, even
|
265
|
+
combining them seamlessly with other queries or other named scopes:
|
151
266
|
|
152
267
|
```ruby
|
153
|
-
Author
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
Author.prolific.a_authors.limit(5)
|
158
|
-
```
|
268
|
+
class Author < CDQManagedOjbect
|
269
|
+
scope :a_authors, where(:name).begins_with('A')
|
270
|
+
scope :prolific, where(:publish_count).gt(99)
|
271
|
+
end
|
159
272
|
|
160
|
-
|
161
|
-
|
162
|
-
just wrap the class: `cdq(Author)`.
|
273
|
+
Author.prolific.a_authors.limit(5)
|
274
|
+
```
|
163
275
|
|
164
276
|
## Using CDQ with a pre-existing model
|
165
277
|
|
166
278
|
If you have an existing app that already manages its own data model, you can
|
167
|
-
use
|
279
|
+
still use CDQ, overriding its stack at any layer:
|
168
280
|
|
169
281
|
```ruby
|
170
282
|
cdq.setup(context: App.delegate.mainContext) # don't set up model or store coordinator
|
@@ -173,12 +285,48 @@ cdq.setup(model: App.delegate.managedObjectModel) # Don't load model
|
|
173
285
|
```
|
174
286
|
|
175
287
|
You cannot use CDQManagedObject as a base class when overriding this way,
|
176
|
-
you'll need to use
|
177
|
-
want to use it with CDQManagedObject without changing its
|
178
|
-
use a <tt>cdq.yml</tt> config file. See
|
288
|
+
you'll need to use the master method, described below. If you have an
|
289
|
+
existing model and want to use it with CDQManagedObject without changing its
|
290
|
+
name, You'll need to use a <tt>cdq.yml</tt> config file. See
|
291
|
+
[CDQConfig](http://github.com/infinitered/cdq/tree/master/motion/cdq/config.rb).
|
292
|
+
|
293
|
+
### Working without model classes using the master method
|
294
|
+
|
295
|
+
If you need or want to work without using CDQManagedObject as your base class,
|
296
|
+
you can use the ```cdq()``` master method. This is a "magic" method, like
|
297
|
+
```rmq()``` in [RubyMotionQuery](http://github.com/infinitered/rmq) or
|
298
|
+
```$()``` in jQuery, which will lift whatever you pass into it into the CDQ
|
299
|
+
universe. The method is available inside all UIResponder classes (so, views and
|
300
|
+
controllers) as well as in the console. You can use it anywhere else by
|
301
|
+
including the model ```CDQ``` into your classes. To use an entity without a
|
302
|
+
model class, just pass its name as a string into the master method, like so
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
cdq('Author').where(:name).eq('Shakespeare')
|
306
|
+
cdq('Author').where(:publish_count).gt(10)
|
307
|
+
cdq('Author').sort_by(:created_at).limit(1).offset(10)
|
308
|
+
```
|
309
|
+
|
310
|
+
Anything you can do with a model, you can also do with the master method, including
|
311
|
+
defining and using named scopes:
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
cdq('Author').scope :a_authors, cdq(:name).begins_with('A')
|
315
|
+
cdq('Author').scope :prolific, cdq(:publish_count).gt(99)
|
316
|
+
```
|
317
|
+
> NOTE: strings and symbols are NOT interchangeable. `cdq('Entity')` gives you a
|
318
|
+
query generator for an entity, but `cdq(:attribute)` starts a predicate for an
|
319
|
+
attribute.
|
320
|
+
|
321
|
+
## Documentation
|
322
|
+
|
323
|
+
* [API](http://rubydoc.info/github/infinitered/cdq)
|
324
|
+
* [Cheat Sheet](https://github.com/infinitered/cdq/wiki/CDQ-Cheat-Sheet)
|
325
|
+
* [Tutorial](https://github.com/infinitered/cdq/wiki/Greenfield-Quick-Start)
|
179
326
|
|
180
327
|
## Things that are currently missing
|
181
328
|
|
182
329
|
* There is no facility for custom migrations yet
|
183
330
|
* There are no explicit validations (but you can define them on your data model)
|
331
|
+
* Lifecycle Callbacks or Observers
|
184
332
|
|
data/lib/cdq/cli.rb
CHANGED
@@ -103,19 +103,7 @@ Options:
|
|
103
103
|
end
|
104
104
|
puts "Done."
|
105
105
|
|
106
|
-
puts %{
|
107
|
-
Now open app/app_delegate.rb, and add
|
108
|
-
|
109
|
-
include CDQ
|
110
|
-
|
111
|
-
at class level, and
|
112
|
-
|
113
|
-
cdq.setup
|
114
|
-
|
115
|
-
wherever you want the stack to get set up, probably right before you set
|
116
|
-
your root controller. Edit your inital schema, create a few models, and
|
117
|
-
you're off and running.
|
118
|
-
}
|
106
|
+
puts %{\n Now edit schemas/0001_initial.rb to define your schema, and you're off and running. }
|
119
107
|
|
120
108
|
end
|
121
109
|
end
|
data/lib/cdq/version.rb
CHANGED
data/motion/cdq.rb
CHANGED
@@ -8,6 +8,41 @@ module CDQ
|
|
8
8
|
|
9
9
|
extend self
|
10
10
|
|
11
|
+
# The master method that will lift a variety of arguments into the CDQ
|
12
|
+
# ecosystem. What it returns depends on the type of the argument passed:
|
13
|
+
#
|
14
|
+
# Class: Finds an entity with the same name as the class and returns a
|
15
|
+
# targeted query. (This is also used internally for dedicated models.)
|
16
|
+
#
|
17
|
+
# cdq(Author).where(:attribute).eq(1).limit(3)
|
18
|
+
#
|
19
|
+
# String: Finds an entity with the name provided in the string and returns a
|
20
|
+
# targeted query.
|
21
|
+
#
|
22
|
+
# cdq('Author').where(:attribute).eq(1).limit(3)
|
23
|
+
#
|
24
|
+
# Symbol: Returns an untargeted partial predicate. This is useful for nested
|
25
|
+
# queries, and for defining scopes.
|
26
|
+
#
|
27
|
+
# Author.scope :singletons, cdq(:attribute).eq(1)
|
28
|
+
# Author.where( cdq(:attribute).eq(1).or.eq(3) ).and(:name).ne("Roger")
|
29
|
+
#
|
30
|
+
# CDQObject: returns the object itself (no-op).
|
31
|
+
#
|
32
|
+
# NSManagedObject: wraps the object in a CDQObjectProxy, which permits
|
33
|
+
# cdq-style queries on the object's relationships.
|
34
|
+
#
|
35
|
+
# emily_dickinson = Author.first
|
36
|
+
# cdq(emily_dickinson).articles.where(:page_count).lt(5).array
|
37
|
+
#
|
38
|
+
# Array: wraps the array in a CDQCollectionProxy, which lets you run queries
|
39
|
+
# relative to the members of the collection.
|
40
|
+
#
|
41
|
+
# emily_dickinson = Author.first
|
42
|
+
# edgar_allen_poe = Author.all[4]
|
43
|
+
# charles_dickens = Author.all[7]
|
44
|
+
# cdq([emily_dickinson, edgar_allen_poe, charles_dickens]).where(:avg_rating).eq(1)
|
45
|
+
#
|
11
46
|
def cdq(obj = nil)
|
12
47
|
obj ||= self
|
13
48
|
|
@@ -48,15 +83,15 @@ module CDQ
|
|
48
83
|
end
|
49
84
|
end
|
50
85
|
|
51
|
-
def self.pollute(klass)
|
52
|
-
end
|
53
|
-
|
54
86
|
end
|
55
87
|
|
88
|
+
|
89
|
+
# @private
|
56
90
|
class UIResponder
|
57
91
|
include CDQ
|
58
92
|
end
|
59
93
|
|
94
|
+
# @private
|
60
95
|
class TopLevel
|
61
96
|
include CDQ
|
62
97
|
end
|