pg_jbuilder 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +468 -0
- data/Rakefile +7 -0
- data/config/database.yml +3 -0
- data/lib/pg_jbuilder.rb +108 -0
- data/lib/pg_jbuilder/railtie.rb +44 -0
- data/lib/pg_jbuilder/version.rb +3 -0
- data/pg_jbuilder.gemspec +30 -0
- data/queries/test1.sql +1 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/test_model.rb +2 -0
- data/spec/dummy/app/queries/test.sql +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +26 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20150210004140_add_test_model.rb +11 -0
- data/spec/dummy/db/schema.rb +25 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/log/development.log +303 -0
- data/spec/dummy/log/test.log +354 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/pg_jbuilder/pg_jbuilder_spec.rb +182 -0
- data/spec/pg_jbuilder/railtie_spec.rb +88 -0
- data/spec/queries/test2.sql +1 -0
- data/spec/spec_helper.rb +29 -0
- metadata +298 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ae34d2f0e3340562b45bf77c7015b26ad1c37f37
|
4
|
+
data.tar.gz: 9e6a3affabb5efb332cd355333ade4c371979be3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cb19034a07ef837b4967edfa1da9a4a2426a8c7ee27d56c975be529608988c3e93c11e8897bf41da075559294f3863533be7e2592ef7358dbf6f698a108628b5
|
7
|
+
data.tar.gz: b02fd0d3f694f40f7a2bdad9656016942f6d70beb4940d57f3e14d8dcb974075ba2d49a6fe80fe09a14d1df8a9fdb028249c0feb43914916d8e0e68db3fc8426
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
2
|
+
# require "guard/rspec/dsl"
|
3
|
+
# dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
# rspec = dsl.rspec
|
5
|
+
# watch(rspec.spec_helper) { rspec.spec_dir }
|
6
|
+
# watch(rspec.spec_support) { rspec.spec_dir }
|
7
|
+
# watch(rspec.spec_files)
|
8
|
+
# ruby = dsl.ruby
|
9
|
+
# dsl.watch_spec_files_for(ruby.lib_files)
|
10
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Tye Shavik <tye@tye.ca>
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,468 @@
|
|
1
|
+
# PgJbuilder
|
2
|
+
|
3
|
+
PgJbuilder provides a wrapper around PostgreSQL's JSON functions ([array_to_json and row_to_json](http://www.postgresql.org/docs/9.3/static/functions-json.html)) allowing you to write queries that serialize their results directly to a JSON string. This completely bypasses creating ActiveRecord objects and using Arel giving a large speed boost. It is especially useful for creating JSON APIs with low response times.
|
4
|
+
|
5
|
+
## Benefits
|
6
|
+
|
7
|
+
Using PostgreSQL to serialize your query results to JSON is much
|
8
|
+
faster than serializing the records inside of Ruby.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add to your Gemfile:
|
13
|
+
|
14
|
+
gem 'pg_jbuilder'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
## Requirements
|
21
|
+
|
22
|
+
PgJbuilder requires:
|
23
|
+
|
24
|
+
- PostgreSQL 9.2+
|
25
|
+
- ActiveRecord 3.0+
|
26
|
+
|
27
|
+
Compatible with Rails 3.0+
|
28
|
+
|
29
|
+
## Initializing the gem in a non-Rails environment
|
30
|
+
|
31
|
+
If you're using Rails you don't need to do any additional setup. To use
|
32
|
+
the gem outside of Rails there are a few things you need to do:
|
33
|
+
|
34
|
+
1. Set the database connection. This needs to be an ActiveRecord connection.
|
35
|
+
|
36
|
+
PgJbuilder.connection = ActiveRecord::Base.connection
|
37
|
+
This can also be a lambda{} that when called returns a connection.
|
38
|
+
|
39
|
+
2. Set the path where your queries will be. For example if your queries are in the app/queries directory:
|
40
|
+
|
41
|
+
PgJbuilder.paths.unshift File.join(File.dirname(__FILE__),'app','queries')
|
42
|
+
|
43
|
+
3. The examples below are for Rails. For non-Rails applications where
|
44
|
+
the examples below use `select_object` and `select_array` you can use
|
45
|
+
`PgJbuilder.render_object`, `PbJbuilder.render_array`,
|
46
|
+
`PgJbuilder.render` to render your
|
47
|
+
queries. Once rendered they can be sent to your database and will return
|
48
|
+
a single string of JSON. For example:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
def user_json id
|
52
|
+
sql = PgJbuilder.render_object 'users/show', id: id
|
53
|
+
ActiveRecord::Base.connection.select_value(sql)
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
## Usage
|
58
|
+
|
59
|
+
For Rails applications queries are expected to be in `app/queries`. You can change this
|
60
|
+
by creating an initializer and adding a different path to `PgJbuilder.paths` (see the example in Initializing the gem in a non-Rails environment).
|
61
|
+
|
62
|
+
### Returning a simple object:
|
63
|
+
|
64
|
+
1. Create a query that will select the columns you want to return in your JSON. For example to return a User as json you might create a query called `app/queries/users/show.sql`:
|
65
|
+
|
66
|
+
```sql
|
67
|
+
SELECT
|
68
|
+
users.id,
|
69
|
+
users.email,
|
70
|
+
users.first_name,
|
71
|
+
users.last_name
|
72
|
+
FROM users
|
73
|
+
WHERE id = {{id}}
|
74
|
+
ORDER BY id ASC
|
75
|
+
```
|
76
|
+
|
77
|
+
2. Add a method to your model that will render the JSON. For the user
|
78
|
+
example you would add this to app/models/user.rb
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
class User < ActiveRecord::Base
|
82
|
+
def show_json
|
83
|
+
select_object 'users/show', id: id
|
84
|
+
end
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
Note that queries use Handlebars for templating. We pass in the id to
|
89
|
+
`select_object` then the `{{id}}` in the template will be replaced
|
90
|
+
with this value. Read more on Handlebars syntax [on their
|
91
|
+
website](http://handlebarsjs.com/expressions.html).
|
92
|
+
|
93
|
+
This query would return a JSON object like:
|
94
|
+
```json
|
95
|
+
{
|
96
|
+
"id": 1,
|
97
|
+
"email": "mbolton@initech.com",
|
98
|
+
"first_name": "Michael",
|
99
|
+
"last_name": "Bolton"
|
100
|
+
}
|
101
|
+
```
|
102
|
+
|
103
|
+
Since this is a JSON object and not an array the query must return
|
104
|
+
only a single row. If more than one row is returned by the query
|
105
|
+
PostgreSQL will raise an error and the query will fail.
|
106
|
+
|
107
|
+
3. Call the `show_json` method added to `User` to return the user as
|
108
|
+
JSON. For example if you were using this in a JSON API then in your controller you might use:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
class UsersController < ApplicationController
|
112
|
+
before_filter :load_user
|
113
|
+
|
114
|
+
def show
|
115
|
+
render json: @user.show_json
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def load_user
|
121
|
+
@user = User.find(params[:id])
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
### Returning a simple array
|
127
|
+
|
128
|
+
1. Create a query that will return all the rows and columns you want
|
129
|
+
in your JSON. For example if you want to return a list of users we
|
130
|
+
would create a query in `app/queries/users/index.sql` like this:
|
131
|
+
|
132
|
+
```sql
|
133
|
+
SELECT
|
134
|
+
users.id,
|
135
|
+
users.email,
|
136
|
+
users.first_name,
|
137
|
+
users.last_name
|
138
|
+
FROM users
|
139
|
+
ORDER BY id
|
140
|
+
```
|
141
|
+
|
142
|
+
2. Add a method to your `User` model that renders the array:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
class User < ActiveRecord::Base
|
146
|
+
def self.index_json
|
147
|
+
select_array 'users/index'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
This would return a JSON array like this:
|
153
|
+
|
154
|
+
```json
|
155
|
+
[
|
156
|
+
{
|
157
|
+
"id": 1,
|
158
|
+
"email": "mbolton@initech.com",
|
159
|
+
"first_name": "Michael",
|
160
|
+
"last_name": "Bolton"
|
161
|
+
},
|
162
|
+
{
|
163
|
+
"id": 2,
|
164
|
+
"email": "pgibbons@initech.com",
|
165
|
+
"first_name": "Peter",
|
166
|
+
"last_name": "Gibbons"
|
167
|
+
},
|
168
|
+
{
|
169
|
+
"id": 3,
|
170
|
+
"email": "snagheenanajar@initech.com",
|
171
|
+
"first_name": "Samir",
|
172
|
+
"last_name": "Nagheenanajar"
|
173
|
+
}
|
174
|
+
]
|
175
|
+
```
|
176
|
+
|
177
|
+
3. Call the method added to the `User` model to return the JSON. For
|
178
|
+
example in your controller you might add:
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
class UsersController < ApplicationController
|
182
|
+
def index
|
183
|
+
render json: User.index_json
|
184
|
+
end
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
### Quoting/Escaping values
|
189
|
+
|
190
|
+
You can use the `{{quote}}` helper to escape user inputted values to
|
191
|
+
make them safe to include in the query. For example if your query is
|
192
|
+
`app/queries/users/search.sql`:
|
193
|
+
|
194
|
+
```sql
|
195
|
+
SELECT users.id
|
196
|
+
FROM users
|
197
|
+
WHERE
|
198
|
+
users.first_name = {{quote first_name}}
|
199
|
+
```
|
200
|
+
|
201
|
+
and you call the query:
|
202
|
+
```ruby
|
203
|
+
select_array 'users/search', first_name: 'John'
|
204
|
+
```
|
205
|
+
|
206
|
+
it will render the query as:
|
207
|
+
```sql
|
208
|
+
SELECT users.id
|
209
|
+
FROM users
|
210
|
+
WHERE
|
211
|
+
users.first_name = 'John'
|
212
|
+
```
|
213
|
+
|
214
|
+
Without the quote helper it would render as:
|
215
|
+
|
216
|
+
```sql
|
217
|
+
SELECT users.id
|
218
|
+
FROM users
|
219
|
+
WHERE
|
220
|
+
users.first_name = John
|
221
|
+
```
|
222
|
+
|
223
|
+
without the quotes which would allow SQL injection attacks. `{{quote}}`
|
224
|
+
will also escape quotes for example:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
select_array 'users/search', first_name: "Jo'hn"
|
228
|
+
```
|
229
|
+
|
230
|
+
will render as:
|
231
|
+
```sql
|
232
|
+
SELECT users.id
|
233
|
+
FROM users
|
234
|
+
WHERE
|
235
|
+
users.first_name = 'Jo''hn'
|
236
|
+
```
|
237
|
+
|
238
|
+
### Partials
|
239
|
+
|
240
|
+
You can include partials in your template using the `{{include}}`
|
241
|
+
helper. For example you might refactor the SELECT portion of your query
|
242
|
+
into its own partial `app/queries/users/select.sql`
|
243
|
+
|
244
|
+
```sql
|
245
|
+
SELECT
|
246
|
+
users.id,
|
247
|
+
users.first_name,
|
248
|
+
users.last_name,
|
249
|
+
users.email
|
250
|
+
```
|
251
|
+
|
252
|
+
Then in `app/queries/users/show.sql` you would have:
|
253
|
+
|
254
|
+
```sql
|
255
|
+
{{include 'users/select'}}
|
256
|
+
FROM users
|
257
|
+
WHERE id = {{id}}
|
258
|
+
```
|
259
|
+
|
260
|
+
Variables passed into a query will automatically be passed into the
|
261
|
+
partial. In the above example there is a `{{id}}` variable. You would
|
262
|
+
also be able to use this variable in the partial.
|
263
|
+
|
264
|
+
You can pass additional variables into the partial using this syntax:
|
265
|
+
|
266
|
+
`{{include 'template_name' variable1='value' variable2='value' ...}}`
|
267
|
+
|
268
|
+
### Embedding objects and arrays
|
269
|
+
|
270
|
+
#### Objects
|
271
|
+
|
272
|
+
You can embed objects using the `{{object}}` helper. For example if you
|
273
|
+
want to have a user object inside a your comment index in
|
274
|
+
`app/queries/comments/index.sql`:
|
275
|
+
|
276
|
+
```sql
|
277
|
+
SELECT
|
278
|
+
comments.id,
|
279
|
+
comments.body,
|
280
|
+
{{#object}}
|
281
|
+
SELECT
|
282
|
+
users.id,
|
283
|
+
users.first_name,
|
284
|
+
users.last_name,
|
285
|
+
users.email
|
286
|
+
FROM users
|
287
|
+
WHERE
|
288
|
+
users.id = comments.user_id
|
289
|
+
{{/object}} AS user
|
290
|
+
FROM comments
|
291
|
+
ORDER BY id
|
292
|
+
```
|
293
|
+
|
294
|
+
This would create a JSON object like:
|
295
|
+
```json
|
296
|
+
{
|
297
|
+
"id": 1,
|
298
|
+
"body": "This is my comment",
|
299
|
+
"user": {
|
300
|
+
"id": 100,
|
301
|
+
"username": "witty_commenter"
|
302
|
+
}
|
303
|
+
}
|
304
|
+
```
|
305
|
+
|
306
|
+
You can also refactor the object into a partial. So you could create a
|
307
|
+
query in `app/queries/users/object.sql`:
|
308
|
+
|
309
|
+
```sql
|
310
|
+
SELECT
|
311
|
+
users.id,
|
312
|
+
users.first_name,
|
313
|
+
users.last_name,
|
314
|
+
users.email
|
315
|
+
FROM users
|
316
|
+
WHERE
|
317
|
+
users.id = {{id}}
|
318
|
+
```
|
319
|
+
|
320
|
+
Then include it using this syntax in `app/queries/comments/index.sql`:
|
321
|
+
|
322
|
+
```sql
|
323
|
+
SELECT
|
324
|
+
comments.id,
|
325
|
+
comments.body,
|
326
|
+
{{object 'users/object' id='comments.user_id'}} AS user
|
327
|
+
FROM comments
|
328
|
+
ORDER BY id
|
329
|
+
```
|
330
|
+
|
331
|
+
This would produce the same JSON as above.
|
332
|
+
|
333
|
+
#### Arrays
|
334
|
+
|
335
|
+
Embedding arrays works just like embedding objects but uses the
|
336
|
+
`{{array}}` helper. For example if you have a user object in
|
337
|
+
`app/queries/users/show.sql` and want to return a list of the user's
|
338
|
+
comments inside the user object:
|
339
|
+
|
340
|
+
```sql
|
341
|
+
SELECT
|
342
|
+
users.id,
|
343
|
+
users.first_name,
|
344
|
+
users.last_name,
|
345
|
+
users.email,
|
346
|
+
{{#array}}
|
347
|
+
SELECT
|
348
|
+
comments.id,
|
349
|
+
comments.body
|
350
|
+
FROM comments
|
351
|
+
WHERE comments.user_id = users.id
|
352
|
+
{{/array}} AS comments
|
353
|
+
FROM users
|
354
|
+
WHERE id = {{id}}
|
355
|
+
```
|
356
|
+
|
357
|
+
This would return a JSON object like:
|
358
|
+
|
359
|
+
```json
|
360
|
+
{
|
361
|
+
"id": 1,
|
362
|
+
"username": "witty_commenter",
|
363
|
+
"comments": [
|
364
|
+
{
|
365
|
+
"id": 100,
|
366
|
+
"body": "Witty Comment #1"
|
367
|
+
},
|
368
|
+
{
|
369
|
+
"id": 200,
|
370
|
+
"body": "Witty Comment #2"
|
371
|
+
}
|
372
|
+
]
|
373
|
+
}
|
374
|
+
```
|
375
|
+
|
376
|
+
Just like with `{{object}}` you can refactor your arrays into a partial.
|
377
|
+
So if you have `app/queries/users/comments.sql`
|
378
|
+
|
379
|
+
```sql
|
380
|
+
SELECT
|
381
|
+
comments.id,
|
382
|
+
comments.body
|
383
|
+
FROM comments
|
384
|
+
WHERE comments.user_id = {{user_id}}
|
385
|
+
```
|
386
|
+
|
387
|
+
then in `app/queries/users/show.sql` you can have:
|
388
|
+
|
389
|
+
```sql
|
390
|
+
SELECT
|
391
|
+
users.id,
|
392
|
+
users.username,
|
393
|
+
{{array 'users/comments' user_id='users.id'}} AS comments
|
394
|
+
FROM users
|
395
|
+
WHERE id = {{id}}
|
396
|
+
```
|
397
|
+
|
398
|
+
### Pagination
|
399
|
+
|
400
|
+
To do pagination you need to execute two queries. One to count the rows,
|
401
|
+
then another to return the results with a LIMIT and OFFSET. To
|
402
|
+
accomplish this with pg_jbuilder your query would have to look like
|
403
|
+
this:
|
404
|
+
|
405
|
+
```sql
|
406
|
+
SELECT
|
407
|
+
{{#if count}}
|
408
|
+
COUNT(*) AS total_rows
|
409
|
+
{{else}}
|
410
|
+
comments.id,
|
411
|
+
comments.body
|
412
|
+
{{/if}}
|
413
|
+
FROM comments
|
414
|
+
{{#unless count}}
|
415
|
+
ORDER BY id
|
416
|
+
LIMIT {{per_page}}
|
417
|
+
OFFSET ({{quote page}} - 1) * {{per_page}}
|
418
|
+
{{/unless}}
|
419
|
+
```
|
420
|
+
|
421
|
+
Then in your model:
|
422
|
+
```ruby
|
423
|
+
class Comment < ActiveRecord::Base
|
424
|
+
PER_PAGE = 20
|
425
|
+
def self.count_index_json attrs={}
|
426
|
+
attrs[:count] = true
|
427
|
+
attrs[:per_page] = PER_PAGE
|
428
|
+
select_value('comments/index').to_i
|
429
|
+
end
|
430
|
+
|
431
|
+
def self.index_json attrs={}
|
432
|
+
attrs[:per_page] = PER_PAGE
|
433
|
+
select_array 'comments/index', attrs
|
434
|
+
end
|
435
|
+
end
|
436
|
+
```
|
437
|
+
|
438
|
+
`select_value` will return render your query and return a single value
|
439
|
+
from it.
|
440
|
+
|
441
|
+
And in your controller:
|
442
|
+
```ruby
|
443
|
+
class CommentsController < ApplicationController
|
444
|
+
def index
|
445
|
+
count = Comment.count_index_json(index_params)
|
446
|
+
headers['X-Pagination-Total-Entries'] = count.to_s
|
447
|
+
render json: Comment.index_json(index_params)
|
448
|
+
end
|
449
|
+
|
450
|
+
private
|
451
|
+
|
452
|
+
def index_params
|
453
|
+
params.permit :page
|
454
|
+
end
|
455
|
+
end
|
456
|
+
```
|
457
|
+
|
458
|
+
The API consumer can then read the `X-Pagination-Total-Entries` to see the
|
459
|
+
total number of entries and can pass a `page` parameter to specify which
|
460
|
+
page to fetch.
|
461
|
+
|
462
|
+
## Contributing
|
463
|
+
|
464
|
+
1. Fork it ( https://github.com/[my-github-username]/pg-json/fork )
|
465
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
466
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
467
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
468
|
+
5. Create a new Pull Request
|