sinja 1.1.0.pre4 → 1.2.0.pre2

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/README.md +96 -29
  4. data/demo-app/.dockerignore +1 -0
  5. data/demo-app/Dockerfile +26 -0
  6. data/demo-app/Gemfile +12 -1
  7. data/demo-app/README.md +39 -24
  8. data/demo-app/Rakefile +36 -0
  9. data/demo-app/app.rb +3 -10
  10. data/demo-app/boot.rb +0 -4
  11. data/demo-app/classes/author.rb +3 -4
  12. data/demo-app/{base.rb → classes/base.rb} +2 -1
  13. data/demo-app/classes/comment.rb +1 -2
  14. data/demo-app/classes/post.rb +17 -10
  15. data/demo-app/classes/tag.rb +7 -3
  16. data/extensions/sequel/Gemfile +4 -0
  17. data/extensions/sequel/LICENSE.txt +21 -0
  18. data/extensions/sequel/README.md +274 -0
  19. data/extensions/sequel/Rakefile +10 -0
  20. data/extensions/sequel/bin/console +14 -0
  21. data/extensions/sequel/bin/setup +8 -0
  22. data/extensions/sequel/lib/sinatra/jsonapi/sequel.rb +7 -0
  23. data/extensions/sequel/lib/sinja-sequel.rb +2 -0
  24. data/extensions/sequel/lib/sinja/sequel.rb +110 -0
  25. data/extensions/sequel/lib/sinja/sequel/core.rb +72 -0
  26. data/extensions/sequel/lib/sinja/sequel/helpers.rb +78 -0
  27. data/extensions/sequel/lib/sinja/sequel/version.rb +6 -0
  28. data/extensions/sequel/sinja-sequel.gemspec +29 -0
  29. data/extensions/sequel/test/test_helper.rb +3 -0
  30. data/lib/sinja.rb +40 -18
  31. data/lib/sinja/config.rb +4 -3
  32. data/lib/sinja/helpers/serializers.rb +2 -1
  33. data/lib/sinja/relationship_routes/has_many.rb +8 -9
  34. data/lib/sinja/relationship_routes/has_one.rb +1 -1
  35. data/lib/sinja/resource.rb +2 -1
  36. data/lib/sinja/resource_routes.rb +2 -2
  37. data/lib/sinja/version.rb +1 -1
  38. data/sinja.gemspec +5 -7
  39. metadata +39 -11
  40. data/.rspec +0 -2
  41. data/lib/sinja/extensions/sequel.rb +0 -53
  42. data/lib/sinja/helpers/sequel.rb +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a86013c139ad0c6cd3555443076a4c813c8cedc6
4
- data.tar.gz: 7c3dc7d285fb817bb9e4c6003bc24c0cb8d2b1f2
3
+ metadata.gz: 7194e1502968ad1c77f29a86eba2142a02e9fab0
4
+ data.tar.gz: d60c872b2a8b8d5555f18eb2a3064fd748ab4ec8
5
5
  SHA512:
6
- metadata.gz: 86a0909d1e859b4f2177de1d71c91b60fa5bc0160c8b1568f94acc100ce84c01157439633e89124eed2e09318a3b4ffb0aa6596fc7bae3a09ee88a4e9132ca43
7
- data.tar.gz: 21f0f20bda31d9a6954437f66848eb47f7c13dd8e8250992bb259c9791f7cb3fa7b39f6ba8291101f7128bf8b7add9b8e87b32c768d95d3924a839fee90627c6
6
+ metadata.gz: a42b7e9f8c15e748145b731f9329c7bcce307fb4224ba1f33c2172faacb41fd75dcebe02374e9aa6101fef422f8d12bf09f1c32fdfb4b2a45239e97bd28643c1
7
+ data.tar.gz: ec35d6bd75b8b47b03ad9a6803407f03ca5c89593389962820de22c1a63de6c7ce7309b592264e8ac961ad552547658ff8723eeac22f8a0f1b8b628cd3c8a9da
data/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
- gem 'munson', '~> 0.3',
4
+ gem 'sinja-sequel', :require=>false, :path=>'extensions/sequel'
5
+ gem 'munson', '~> 0.3', :require=>false,
5
6
  :git=>'https://github.com/mwpastore/munson', :branch=>'develop'
data/README.md CHANGED
@@ -1,8 +1,18 @@
1
1
  # Sinja (Sinatra::JSONAPI)
2
2
 
3
+ <!--
4
+ Title: Sinja
5
+ Description: RESTful, {json:api}-compliant web services in Sinatra
6
+ Author: Mike Pastore
7
+ Keywords: JSON, API, JSONAPI, JSON:API, {json:api}, Ruby, Sinatra, JSONAPI::Serializers, jsonapi-serializers
8
+ -->
9
+
3
10
  [![Gem Version](https://badge.fury.io/rb/sinja.svg)](https://badge.fury.io/rb/sinja)
11
+ [![Dependency Status](https://gemnasium.com/badges/github.com/mwpastore/sinja.svg)](https://gemnasium.com/github.com/mwpastore/sinja)
4
12
  [![Build Status](https://travis-ci.org/mwpastore/sinja.svg?branch=master)](https://travis-ci.org/mwpastore/sinja)
5
- [![Chat](https://badges.gitter.im/sinja-rb/Lobby.svg)](https://gitter.im/sinja-rb/Lobby)
13
+
14
+ [![Chat in #sinja-rb on Gitter](https://badges.gitter.im/sinja-rb/Lobby.svg)](https://gitter.im/sinja-rb/Lobby)
15
+ [![Chat in #-ember-data on Slack](https://ember-community-slackin.herokuapp.com/badge.svg)](https://ember-community-slackin.herokuapp.com/?channel=-ember-data)
6
16
 
7
17
  Sinja is a [Sinatra][1] [extension][10] for quickly building [RESTful][11],
8
18
  [{json:api}][2]-[compliant][7] web services, leveraging the excellent
@@ -26,6 +36,7 @@ the {json:api} specification is).
26
36
  - [Commonly Used](#commonly-used)
27
37
  - [Less-Commonly Used](#less-commonly-used)
28
38
  - [Performance](#performance)
39
+ - [Extensions](#extensions)
29
40
  - [Comparison with JSONAPI::Resources](#comparison-with-jsonapiresources)
30
41
  - [Basic Usage](#basic-usage)
31
42
  - [Configuration](#configuration)
@@ -48,6 +59,7 @@ the {json:api} specification is).
48
59
  - [`has_many`](#has_many)
49
60
  - [`fetch {..}` => Array](#fetch---array)
50
61
  - [`clear {..}` => TrueClass?](#clear---trueclass)
62
+ - [`replace {|rios| ..}` => TrueClass?](#replace-rios---trueclass)
51
63
  - [`merge {|rios| ..}` => TrueClass?](#merge-rios---trueclass)
52
64
  - [`subtract {|rios| ..}` => TrueClass?](#subtract-rios---trueclass)
53
65
  - [Advanced Usage](#advanced-usage)
@@ -346,6 +358,13 @@ written them verbosely. The main caveat is that there are quite a few block
346
358
  closures, which don't perform as well as normal methods in Ruby. Feedback
347
359
  welcome.
348
360
 
361
+ ### Extensions
362
+
363
+ Sinja extensions provide additional helpers, DSL, and configuration, packaging
364
+ ORM-specific boilerplate as separate gems. At the moment, the only available
365
+ extension is for [Sequel](/extensions/sequel), but community contributions are
366
+ welcome!
367
+
349
368
  ### Comparison with JSONAPI::Resources
350
369
 
351
370
  | Feature | JR | Sinja |
@@ -436,7 +455,7 @@ configure_jsonapi do |c|
436
455
 
437
456
  # You can't set this directly; see "Query Parameters" below
438
457
  #c.query_params = {
439
- # :include=>[], :fields=>{}, :filter=>{}, :page=>{}, :sort=>{}
458
+ # :include=>[], :fields=>{}, :filter=>{}, :page=>{}, :sort=>[]
440
459
  #}
441
460
 
442
461
  #c.page_using = {} # see "Paging" below
@@ -630,6 +649,18 @@ has_many :bars do
630
649
  end
631
650
  ```
632
651
 
652
+ ##### `replace {|rios| ..}` => TrueClass?
653
+
654
+ Take an array of [resource identifier object][22] hashes and update
655
+ (add/remove) the relationships on `resource`. To serialize the updated linkage
656
+ on the response, refresh or reload `resource` (if necessary) and return a
657
+ truthy value.
658
+
659
+ In principle, `replace` should delete all members of the existing collection
660
+ and insert all members of a new collection, but in practice&mdash;for
661
+ performance reasons, especially with large collections and/or complex
662
+ constraints&mdash;it may be prudent to simply apply a delta.
663
+
633
664
  ##### `merge {|rios| ..}` => TrueClass?
634
665
 
635
666
  Take an array of [resource identifier object][22] hashes and update (add unless
@@ -735,6 +766,7 @@ configure_jsonapi do |c|
735
766
  c.default_has_many_roles = {
736
767
  fetch: :user,
737
768
  clear: :admin,
769
+ replace: :admin,
738
770
  merge: :admin,
739
771
  subtract: :admin
740
772
  }
@@ -835,8 +867,8 @@ resource :foos do
835
867
  end
836
868
  end
837
869
 
838
- create(roles: :user) { |attr| .. }
839
- update(roles: :owner) { |attr| .. }
870
+ create(roles: :user) {|attr| .. }
871
+ update(roles: :owner) {|attr| .. }
840
872
  end
841
873
  ```
842
874
 
@@ -934,7 +966,7 @@ For example, to implement sorting using Sequel:
934
966
  ```ruby
935
967
  helpers do
936
968
  def sort(collection, fields={})
937
- collection.order(*fields.map { |k, v| Sequel.send(v, k) })
969
+ collection.order(*fields.map {|k, v| Sequel.send(v, k) })
938
970
  end
939
971
  end
940
972
 
@@ -968,7 +1000,7 @@ Allow clients to page the collections returned by the `index` and `fetch`
968
1000
  action helpers by defining a `page` helper in the appropriate scope that takes
969
1001
  a collection and a hash of `page` query parameters (with its top-level keys
970
1002
  dedasherized and symbolized) and returns the paged collection along with a
971
- special nested hash used to build the paging links.
1003
+ special nested hash used as root metadata and to build the paging links.
972
1004
 
973
1005
  The top-level keys of the hash returned by this method must be members of the
974
1006
  set: {`:self`, `:first`, `:prev`, `:next`, `:last`}. The values of the hash are
@@ -1000,8 +1032,8 @@ Could be used to build the following top-level links in the response document:
1000
1032
  You must also set the `page_using` configurable to a hash of symbols
1001
1033
  representing the paging fields used in your application (for example, `:number`
1002
1034
  and `:size` for the above example) along with their default values (or `nil`).
1003
- Please see the [Sequel helpers](/lib/sinja/helpers/sequel.rb) in this
1004
- repository for a detailed, working example.
1035
+ Please see the [Sequel extension](/extensions/sequel) in this repository for a
1036
+ detailed, working example.
1005
1037
 
1006
1038
  The easiest way to page a collection by default is to tweak the post-processed
1007
1039
  query parameter(s) in a `before_<action>` hook:
@@ -1036,10 +1068,6 @@ helpers do
1036
1068
  end
1037
1069
  ```
1038
1070
 
1039
- (Note that in addition to finalizing Sequel datasets with `#all`, you should
1040
- also enable the `:tactical_eager_loading` plugin for the best compatibility
1041
- with JSONAPI::Serializers.)
1042
-
1043
1071
  ### Conflicts
1044
1072
 
1045
1073
  If your database driver raises exceptions on constraint violations, you should
@@ -1174,12 +1202,11 @@ request will fail and any database changes will be rolled back (given a
1174
1202
  `transaction` helper). Note that the user's role must grant them access to call
1175
1203
  either `graft` or `create`.
1176
1204
 
1177
- `create` and `update` are the only two action helpers that trigger sideloading;
1178
- `graft`, `merge`, and `clear` are the only action helpers invoked by
1205
+ `create` and `update` are the resource action helpers that trigger sideloading;
1206
+ `graft` and `prune` are the to-one action helpers invoked by sideloading; and
1207
+ `replace`, `merge`, and `clear` are the to-many action helpers invoked by
1179
1208
  sideloading. You must indicate which combinations are valid using the
1180
- `:sideload_on` action helper option. (Note that if you want to sideload `merge`
1181
- on `update`, you must define a `clear` action helper and allow it to sideload
1182
- on `update` as well.) For example:
1209
+ `:sideload_on` action helper option. For example:
1183
1210
 
1184
1211
  ```ruby
1185
1212
  resource :photos do
@@ -1187,24 +1214,64 @@ resource :photos do
1187
1214
  def find(id) ..; end
1188
1215
  end
1189
1216
 
1190
- create { |attr| .. }
1191
- update { |attr| .. }
1217
+ create {|attr| .. }
1192
1218
 
1193
1219
  has_one :photographer do
1194
- # Allow `create' to sideload the Photographer
1195
- graft(sideload_on: :create) { |rio| .. }
1220
+ # Allow `create' to sideload Photographer
1221
+ graft(sideload_on: :create) {|rio| .. }
1196
1222
  end
1197
1223
 
1198
1224
  has_many :tags do
1199
- # Allow `create' and `update' to sideload Tags
1200
- merge(sideload_on: [:create, :update]) { |rios| .. }
1201
-
1202
- # Allow `update' to clear Tags before sideloading them
1203
- clear(sideload_on: :update) { .. }
1225
+ # Allow `create' to sideload Tags
1226
+ merge(sideload_on: :create) {|rios| .. }
1204
1227
  end
1205
1228
  end
1206
1229
  ```
1207
1230
 
1231
+ The following matrix outlines which combinations of action helpers and
1232
+ `:sideload_on` options enable which behaviors:
1233
+
1234
+ <small>
1235
+ <table>
1236
+ <thead>
1237
+ <tr>
1238
+ <th rowspan="2">Desired behavior</th>
1239
+ <th colspan="2">For to-one relationship(s)</th>
1240
+ <th colspan="2">For to-many relationship(s)</th>
1241
+ </tr>
1242
+ <tr>
1243
+ <th>Define Action Helper</th>
1244
+ <th>With <code>:sideload_on</code></th>
1245
+ <th>Define Action Helper</th>
1246
+ <th>With <code>:sideload_on</code></th>
1247
+ </tr>
1248
+ </thead>
1249
+ <tbody>
1250
+ <tr>
1251
+ <td>Set relationship(s) when creating resource</td>
1252
+ <td><code>graft</code></td>
1253
+ <td><code>:create</code></td>
1254
+ <td><code>merge</code></td>
1255
+ <td><code>:create</code></td>
1256
+ </tr>
1257
+ <tr>
1258
+ <td>Set relationship(s) when updating resource</td>
1259
+ <td><code>graft</code></td>
1260
+ <td><code>:update</code></td>
1261
+ <td><code>replace</code></td>
1262
+ <td><code>:update</code></td>
1263
+ </tr>
1264
+ <tr>
1265
+ <td>Delete relationship(s) when updating resource</td>
1266
+ <td><code>prune</code></td>
1267
+ <td><code>:update</code></td>
1268
+ <td><code>clear</code></td>
1269
+ <td><code>:update</code></td>
1270
+ </tr>
1271
+ </tbody>
1272
+ </table>
1273
+ </small>
1274
+
1208
1275
  #### Avoiding Null Foreign Keys
1209
1276
 
1210
1277
  Now, let's say our DBA is forward-thinking and wants to make the foreign key
@@ -1271,9 +1338,9 @@ end
1271
1338
  ```
1272
1339
 
1273
1340
  Note that the `validate!` hook is _only_ invoked from within transactions
1274
- involving the `create` and `update` action helpers (and any dependent `graft`
1275
- and `merge` action helpers), so this deferred validation pattern is only
1276
- appropriate in those cases. You must use immedate validation in all other
1341
+ involving the `create` and `update` action helpers (and any action helpers
1342
+ invoked via the sideloading mechanism), so this deferred validation pattern is
1343
+ only appropriate in those cases. You must use immedate validation in all other
1277
1344
  cases. The `sideloaded?` helper is provided to help disambiguate edge cases.
1278
1345
 
1279
1346
  > TODO: The following three sections are a little confusing. Rewrite them.
@@ -0,0 +1 @@
1
+ Gemfile.lock
@@ -0,0 +1,26 @@
1
+ FROM ruby:2.3-alpine
2
+ ARG container_port=4567
3
+ ENV container_port=$container_port
4
+
5
+ RUN apk --no-cache upgrade
6
+ RUN apk --no-cache add \
7
+ sqlite-libs
8
+
9
+ COPY Gemfile /app/
10
+ RUN apk --no-cache add --virtual build-dependencies \
11
+ build-base \
12
+ git \
13
+ ruby-dev \
14
+ sqlite-dev \
15
+ && cd /app \
16
+ && DOCKER_BUILD=true bundle install --jobs=4 \
17
+ && apk del build-dependencies
18
+
19
+ COPY . /app
20
+ RUN chown -R nobody:nogroup /app
21
+
22
+ USER nobody
23
+ WORKDIR /app
24
+ CMD bundle exec ruby app.rb -o 0.0.0.0 -p $container_port
25
+
26
+ EXPOSE $container_port
data/demo-app/Gemfile CHANGED
@@ -1,3 +1,14 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemspec :path=>'..'
3
+ gem 'json', '~> 2.0'
4
+ gem 'sequel', '~> 4.41'
5
+ gem 'sinatra', '>= 2.0.0.beta2', '< 3'
6
+ gem 'sinatra-contrib', '>= 2.0.0.beta2', '< 3'
7
+ unless ENV.key?('DOCKER_BUILD')
8
+ gem 'sinja', path: '..'
9
+ gem 'sinja-sequel', path: '../extensions/sequel'
10
+ else
11
+ gem 'sinja'
12
+ gem 'sinja-sequel'
13
+ end
14
+ gem 'sqlite3', '~> 1.3'
data/demo-app/README.md CHANGED
@@ -1,38 +1,51 @@
1
1
  ## Demo App
2
2
 
3
- This is the demo app for Sinja, used as an example of and for testing Sinja. It
4
- is a very simplistic blog-like application with database tables, models,
5
- serializers, and controllers for authors, posts, comments, and tags. It uses
6
- [Sequel ORM](http://sequel.jeremyevans.net) (and the [Sequel
7
- helpers](/lib/sinja/helpers/sequel.rb) provided with Sinja) with an in-memory
8
- SQLite database, and it works under both MRI/YARV 2.3+ and JRuby 9.1+.
3
+ This is the demo app for Sinja, provided both as an example of and for testing
4
+ Sinja. It uses [Sequel ORM](http://sequel.jeremyevans.net) with an in-memory
5
+ SQLite database and demonstrates the [Sequel extension](/extensions/sequel) for
6
+ Sinja. It works under both MRI/YARV 2.3+ and JRuby 9.1+. It is a very
7
+ simplistic blog-like application with [database
8
+ tables](http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html),
9
+ [models](http://sequel.jeremyevans.net/rdoc/files/README_rdoc.html#label-Sequel+Models),
10
+ [serializers](https://github.com/fotinakis/jsonapi-serializers), and
11
+ [controllers](/) for [authors](/demo-app/classes/author.rb),
12
+ [posts](/demo-app/classes/post.rb), [comments](/demo-app/classes/comment.rb),
13
+ and [tags](/demo-app/classes/tag.rb).
9
14
 
10
15
  ### Usage
11
16
 
12
- Assuming you have a working, Bundler-enabled Ruby environment, simply clone
13
- this repo, `cd` into the `demo-app` subdirectory, and run the following
14
- commands:
17
+ Assuming you have a working, [Bundler](http://bundler.io)-enabled Ruby
18
+ environment, simply clone this repo, `cd` into the `demo-app` subdirectory, and
19
+ run the following commands:
15
20
 
16
21
  ```
17
22
  $ bundle install
18
23
  $ bundle exec ruby app.rb [-p <PORT>]
19
24
  ```
20
25
 
21
- The web server will report the port it's listening on, or you can specify a
22
- port with the `-p` option. It will respond to {json:api}-compliant requests
23
- (don't forget to set an `Accept` header) to `/authors`, `/posts`, `/comments`,
24
- and `/tags`, although not every endpoint is implemented. Log in by setting the
25
- `X-Email` header on the request to the email address of a registered user; the
26
- default administrator email address is all@yourbase.com.
26
+ The web server will report the port it's listening on (most likely 4567), or
27
+ you can specify a port with the `-p` option.
27
28
 
28
- **This is clearly extremely insecure and should not be used as-is in production.
29
- Caveat emptor.**
29
+ Alternatively, if you don't want to clone this repo and set up a Ruby
30
+ environment just for a quick demo, it's available on Docker Cloud as
31
+ [mwpastore/sinja-demo-app](https://cloud.docker.com/app/mwpastore/repository/docker/mwpastore/sinja-demo-app):
32
+
33
+ ```
34
+ $ docker run -it -p 4567:4567 --rm mwpastore/sinja-demo-app
35
+ ```
36
+
37
+ It will respond to {json:api}-compliant requests (don't forget to set an
38
+ `Accept` header) to `/authors`, `/posts`, `/comments`, and `/tags`, although
39
+ not every endpoint is implemented. Log in by setting the `X-Email` header on
40
+ the request to the email address of a registered user; the email address for
41
+ the default admin user is all@yourbase.com. **This is clearly extremely
42
+ insecure and should not be used as-is in production. Caveat emptor.**
30
43
 
31
44
  You can point it at a different database by setting `DATABASE_URL` in the
32
45
  environment before executing `app.rb`. See the relevant [Sequel
33
46
  documentation](http://sequel.jeremyevans.net/rdoc/files/doc/opening_databases_rdoc.html)
34
- for more information. It (rather na&iuml;vely) migrates the database at
35
- startup.
47
+ for more information. It (rather na&iuml;vely) migrates the database and
48
+ creates the default admin user at startup.
36
49
 
37
50
  ### Productionalizing
38
51
 
@@ -40,18 +53,20 @@ You can certainly use this as a starting point for a production application,
40
53
  but you will at least want to:
41
54
 
42
55
  - [ ] Use a persistent database
56
+ - [ ] Remove or change the default admin user
43
57
  - [ ] Separate the class files (e.g. `author.rb`, `post.rb`) into separate
44
- files for the migrations, models, serializers, and Sinja controllers
58
+ files for migrations, models, serializers, and Sinja controllers
45
59
  - [ ] Create a Gemfile using the dependencies in the top-level
46
60
  [gemspec](/sinja.gemspec) as a starting point
47
- - [ ] Add authentication middleware and rewrite the `role` helper to enable
48
- the authorization scheme. You can use the existing roles as defined or
49
- rename them (e.g. use `:admin` instead of `:superuser`)
61
+ - [ ] Add authentication and rewrite the `role` helper to enable the
62
+ authorization scheme. You can use the existing roles as defined or rename
63
+ them (e.g. use `:admin` instead of `:superuser`)
50
64
  - [ ] Use a real application server such as [Puma](http://puma.io) or
51
65
  [Passenger](https://www.phusionpassenger.com) instead of Ruby's
52
66
  stdlib (WEBrick)
53
67
  - [ ] Configure Sequel's connection pool (i.e. `:max_connections`) to match the
54
- application server's thread pool (if any)
68
+ application server's thread pool (if any) size, e.g.
69
+ `Puma.cli_config.options[:max_threads]`
55
70
  - [ ] Add caching directives (i.e. `cache_control`, `expires`, `last_modified`,
56
71
  and `etag`) as appropriate
57
72
 
data/demo-app/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ namespace :docker do
3
+ require 'securerandom'
4
+
5
+ IMAGE = 'mwpastore/sinja-demo-app'
6
+ NAME = SecureRandom.hex(6)
7
+ PORT = 4567
8
+
9
+ def port
10
+ %x{
11
+ docker inspect --format '{{ (index ( index .NetworkSettings.Ports "#{PORT}/tcp") 0).HostPort }}' #{NAME}
12
+ }.chomp
13
+ end
14
+
15
+ task :build do
16
+ sh "docker build --build-arg container_port=#{PORT} --no-cache -t #{IMAGE}:latest #{__dir__}"
17
+ end
18
+
19
+ task :test do
20
+ sh "docker run --rm -d -P --name #{NAME} #{IMAGE}"
21
+ sleep 5
22
+ begin
23
+ sh "curl -sf -H 'Accept: application/vnd.api+json' -I :#{port}/authors"
24
+ ensure
25
+ sh "docker stop #{NAME} >/dev/null || true"
26
+ end
27
+ end
28
+
29
+ task push: [:build, :test] do
30
+ sh "docker push #{IMAGE}:latest"
31
+ end
32
+
33
+ task :run do
34
+ sh "docker run --rm -it -p #{PORT}:#{PORT} #{IMAGE}"
35
+ end
36
+ end
data/demo-app/app.rb CHANGED
@@ -1,28 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
  require 'sinatra'
3
3
  require 'sinatra/jsonapi'
4
+ require 'sinja/sequel/helpers'
4
5
 
5
6
  require_relative 'classes/author'
6
7
  require_relative 'classes/comment'
7
8
  require_relative 'classes/post'
8
9
  require_relative 'classes/tag'
9
10
 
10
- require 'sinja/helpers/sequel'
11
-
12
11
  configure :development do
13
12
  set :server_settings, AccessLog: [] # avoid WEBrick double-logging issue
14
13
  end
15
14
 
16
- configure_jsonapi do |c|
17
- Sinja::Helpers::Sequel.config(c)
18
- end
19
-
20
- helpers do
21
- prepend Sinja::Helpers::Sequel
22
-
15
+ helpers Sinja::Sequel::Helpers do
23
16
  def current_user
24
17
  # TESTING/DEMO PURPOSES ONLY -- DO NOT DO THIS IN PRODUCTION
25
- Author.first_by_email(env['HTTP_X_EMAIL']) if env.key?('HTTP_X_EMAIL')
18
+ @current_user ||= Author.first_by_email(env['HTTP_X_EMAIL']) if env.key?('HTTP_X_EMAIL')
26
19
  end
27
20
 
28
21
  def role