api_presenter 0.4.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e25ab86494a94eea804adefb23b99ead9f1234ef
4
- data.tar.gz: d45fb6fa6067af2e1eddb2853708656c995ef900
2
+ SHA256:
3
+ metadata.gz: b9b45f72f53a0f0d6ddf34ba993ec0a6f5cbcd6fd7f2b8b2436d5963d2f50296
4
+ data.tar.gz: 48d1037e5b1af28c574b421996e9350e119fddc89024aeb7bbb7b059f9cec8e7
5
5
  SHA512:
6
- metadata.gz: ee2a0673296a1b8329423c8fe041671634f367dc49a9d06e8ecf4da87aa9f3f66d0ef43a9c208c497d2befef89874271ce8d185017d0d53321e87eb3f304558d
7
- data.tar.gz: 1107b80b1fa2b9d4a94e2b011f730b95d10a6e42a03143459184655930de6084dc182359ca60b757527d7d0b804296a6e18792dde4192c3e227550a83b3dc9a5
6
+ metadata.gz: 696d7eb80f9327f58f44ab02adfdc14da7a204fa4ae18ac360bde122f5953b55fc986cfa8489fa69c0f4372f3de1d525047512b3e4344b68e35fe3e1fb0f8c54
7
+ data.tar.gz: 1df07f9a061b26b111c00ce52b57a6f89911b914fd787e9e008254da9bf5d01c350ea29af57ea948dd5836b6e2723d979ab946053fd842fb973cbe6c574022e5
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.2.2
4
- before_install: gem install bundler -v 1.10.3
4
+ before_install: gem install bundler -v 2.2.12
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.4.1 (2016-11-10)
2
+
3
+ Bug fix: include `ApplicationApiPresenter` in presenter lookup path.
4
+
5
+ ## 0.4.0 (2016-11-10)
6
+
7
+ Adds presenter generator.
8
+
1
9
  ## 0.3.0 (2016-11-09)
2
10
 
3
11
  Adds configuration options and generator.
data/README.md CHANGED
@@ -1,13 +1,11 @@
1
1
  # ApiPresenter
2
2
 
3
- A much longer readme is coming, including best practices and cautions, but in the meantime lets keep it simple...
3
+ REST APIs provide a concise and conventional means of retrieving resources for a client. But in the real world, clients often have additional data requirements beyond the specifically requested resource(s):
4
4
 
5
- When creating RESTful APIs for web or mobile clients, there are a couple of desirable endpoint behaviors:
5
+ 1. Current user permissions for the returned records, so that the client can intelligently draw its UI (ex: edit/delete buttons).
6
+ 2. Associated data, to mitigate total number of requests (ex: return authors with posts).
6
7
 
7
- * Include permissions so that the client can intelligently draw its UI (ex: edit/delete buttons), while maintaining a single source of truth
8
- * Allow inclusion of associated data to mitigate total number of requests
9
-
10
- ApiPresenter does both of these things, plus a bit more.
8
+ ApiPresenter provides both of these things, plus a bit more.
11
9
 
12
10
  ## Installation
13
11
 
@@ -27,7 +25,7 @@ Or install it yourself as:
27
25
 
28
26
  ## Usage
29
27
 
30
- We'll use a simple blog as the usage example for this gem. The blog has the following model structure:
28
+ ApiPresenter is well suited to large, relational systems. We'll use a blog as the usage example for this gem. The blog has the following model structure:
31
29
 
32
30
  ```ruby
33
31
  class Category < ActiveRecord::Base
@@ -52,22 +50,22 @@ class User < ActiveRecord::Base
52
50
  end
53
51
  ```
54
52
 
55
- When requesting posts from the API, a client may also want any or all of the posts' categories, sub categories, and users. It may also want the current user's policies for the posts to generate correct UI.
53
+ Usage examples will be in the context of requesting posts as the primary collection.
56
54
 
57
55
  ### 0. Generate config file
58
56
 
59
57
  `rails g api_presenter:config`
60
58
 
61
- Generates a configuration file that allows you to override the default querystring params used by the `presenter` concern. More configuration options coming soon.
59
+ Generate your configuration file. Currently, ApiPresenter allows customization of querystring parameter names for including policies and associated resources (see below). More configuration options to come.
62
60
 
63
61
  ### 1. Create your Presenter
64
62
 
65
- Using the supplied generator, generate a presenter class for your ActiveRecord model. The generator will also generate a convenient `ApplicationApiPresenter` class for centralized methods.
63
+ Generate a presenter class for your ActiveRecord model. The generator will also ensure the presence of an `ApplicationApiPresenter` base class for centralized methods.
66
64
 
67
65
  `rails g api_presenter:presenter post`
68
66
 
69
67
  ```ruby
70
- class PostPresenter < ApiApplicationController
68
+ class PostPresenter < ApplicationApiPresenter
71
69
  def associations_map
72
70
  {
73
71
  categories: { associations: { sub_category: :category } },
@@ -86,21 +84,15 @@ class PostPresenter < ApiApplicationController
86
84
  end
87
85
  ```
88
86
 
89
- Presenters have three opt-in methods:
87
+ Presenters can define three opt-in methods:
90
88
 
91
- * `associations_map` The business-dictated includable resources for the ActiveRecord model (`Post`, in this case). Consists of the model name as key and traversal required to preload/load them. In most cases, the value of `associations` will correspond directly to associations on the primary model.
89
+ * `associations_map` Associated resources that you would like to be includable with the primary collection. Consists of the model name as key and the traversal required to preload/load them. In most cases, the value of `associations` will correspond directly to associations on the primary model.
92
90
  * `policy_methods` A list of Pundit policy methods to resolve for the primary collection if policies are requested.
93
- * `policy_associations` Additional records to preload in order to optimize policies that must traverse asscoiations.
91
+ * `policy_associations` Additional associations to preload in order to optimize policies that must traverse asscoiations.
94
92
 
95
93
  ### 2. Enable your controllers
96
94
 
97
- Your presentable collection can be an `ActiveRecord::Relation`, an array of records, or even a single record. Just call `present` on it from your controller action. The preloads will be performed, and the included collections/policies will be available in the `@presenter` instance variable.
98
-
99
- The following configurable querystring params are used by the supplied controller concern's `present` method:
100
-
101
- * `count [Boolean]` Pass true if you just want a count of the primary collection
102
- * `policies [Boolean]` Pass true if you want to resolve policies for the primary collection records
103
- * `include [String, Array]` A comma-delimited list or array of collection names (camelCase or under_scored) to include with the primary collection
95
+ Include the supplied controller concern at your `ApplicationController` level, or on a specific controller. This concern provides the `present` method, which can be called on an `ActiveRecord::Relation`, an array of records, or even a single record (preloading of associated collections is only performed for relations).
104
96
 
105
97
  ```ruby
106
98
  class ApplicationController
@@ -129,17 +121,25 @@ class PostsController < ApplicationController
129
121
  end
130
122
  ```
131
123
 
124
+ Controller params are used to tell the presenter what to load. The default param keys are `count`, `policies`, and `include`:
125
+
126
+ * `count [Boolean]` Pass true if you just want a count of the primary collection.
127
+ * `policies [Boolean]` Pass true if you want to resolve policies for the primary collection.
128
+ * `include [String, Array]` A comma-delimited list or array of collection names (camelCase or under_scored) to include with the primary collection.
129
+
132
130
  ### 3. Render the result
133
131
 
134
- How you ultimately render the primary collection and the data produced by ApiPresenter is up to you. `@presenter` has the following properties:
132
+ After calling the `present` method in a controller action, you access your processed collection through the `@presenter` instance variable. How you ultimately render the data produced by ApiPresenter is up to you.
133
+
134
+ `@presenter` has the following properties:
135
135
 
136
136
  * `collection [Array<ActiveRecord::Base>]` The primary collection that was passed into the presenter. Empty if count requested.
137
137
  * `total_count [Integer]` When using Kaminari or another pagination method that defines a `total_count` property, returns unpaginated count. If the primary collection is not an `ActiveRecord::Relation`, simply returns the number of records.
138
- * `included_collection_names [Array<Symbol>]` Convenience method that returns an array of included collecton model names.
138
+ * `included_collection_names [Array<Symbol>]` Convenience method that returns an array of included collection model names.
139
139
  * `included_collections [Hash]` A hash of included collections, consisting of the model name and corresponding records.
140
140
  * `policies [Array<Hash>]` An array of resolved policies for the primary collection.
141
141
 
142
- Here's an example of how you might render this using JBduiler:
142
+ Here's an example of how you might render your data using JBduiler:
143
143
 
144
144
  ### api/posts/index.json.jbuilder
145
145
 
@@ -176,7 +176,7 @@ end
176
176
 
177
177
  ### 4. Output
178
178
 
179
- Using the code above, our call to `GET /posts` would result in the following JSON:
179
+ Using the code above, our call to `GET /posts?include=categories,subCategories,users&policies=true` would result in the following JSON:
180
180
 
181
181
  ```json
182
182
  {
@@ -206,7 +206,7 @@ Using the code above, our call to `GET /posts` would result in the following JSO
206
206
  }
207
207
  ```
208
208
 
209
- And similarily, for `GET /posts/1`:
209
+ And similarily, for `GET /posts/1?include=categories,subCategories,users&policies=true`:
210
210
 
211
211
  ```json
212
212
  {
@@ -234,12 +234,12 @@ And similarily, for `GET /posts/1`:
234
234
 
235
235
  ### Conditional includes
236
236
 
237
- There are a number of ways you can conditionally include resources, depending, for insatnce, on user type.
237
+ There are a number of ways you can conditionally include resources, depending, for instance, on user type.
238
238
 
239
239
  #### Add conditions inside `associations_map` method
240
240
 
241
241
  ```ruby
242
- class PostPresenter < ApiPresenter::Base
242
+ class PostPresenter < ApiApplicationPresenter
243
243
  def associations_map
244
244
  current_user.admin? ? admin_associations_map : user_associations_map
245
245
  end
@@ -265,7 +265,7 @@ end
265
265
 
266
266
  #### Use `condition` property within `association_map` definition
267
267
 
268
- Via inline string:
268
+ ##### Via inline string
269
269
 
270
270
  ```ruby
271
271
  class PostPresenter < ApiPresenter::Base
@@ -279,7 +279,7 @@ class PostPresenter < ApiPresenter::Base
279
279
  end
280
280
  ```
281
281
 
282
- Via method call:
282
+ ##### Via method call
283
283
 
284
284
  ```ruby
285
285
  class PostPresenter < ApiPresenter::Base
@@ -311,12 +311,10 @@ end
311
311
 
312
312
  ## TODO
313
313
 
314
- * More doc
315
314
  * Decouple from Pundit
316
315
  * Make index policy checking on includes optional
317
316
  * Allow custom collection names
318
317
  * Add test helper to assert presenter was called for a given controller action
319
- * Add presenter generator
320
318
 
321
319
  ## Development
322
320
 
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.add_dependency "activesupport", ">= 3.0.0"
20
20
  spec.add_dependency "pundit"
21
21
  spec.add_development_dependency "activerecord", ">= 4.2.3"
22
- spec.add_development_dependency "bundler", "~> 1.10"
22
+ spec.add_development_dependency "bundler", "~> 2.2.12"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "rspec"
25
25
  spec.add_development_dependency "sqlite3"
@@ -14,8 +14,8 @@ module ApiPresenter
14
14
  #
15
15
  # @return [ApiPresenter::Base]
16
16
  #
17
- def self.call(**kwargs)
18
- new(kwargs).call
17
+ def self.call(current_user: nil, relation:, params: {})
18
+ new(current_user: current_user, relation: relation, params: params).call
19
19
  end
20
20
 
21
21
  # @param current_user [User] Optional. current_user context.
@@ -1,3 +1,3 @@
1
1
  module ApiPresenter
2
- VERSION = "0.4.1"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuval Kordov
8
8
  - Little Blimp
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-11-10 00:00:00.000000000 Z
12
+ date: 2022-06-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -59,14 +59,14 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '1.10'
62
+ version: 2.2.12
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '1.10'
69
+ version: 2.2.12
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rake
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -148,7 +148,7 @@ homepage: http://github.com/uberllama/api_presenter
148
148
  licenses:
149
149
  - MIT
150
150
  metadata: {}
151
- post_install_message:
151
+ post_install_message:
152
152
  rdoc_options: []
153
153
  require_paths:
154
154
  - lib
@@ -163,9 +163,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
163
163
  - !ruby/object:Gem::Version
164
164
  version: '0'
165
165
  requirements: []
166
- rubyforge_project:
167
- rubygems_version: 2.4.6
168
- signing_key:
166
+ rubygems_version: 3.0.9
167
+ signing_key:
169
168
  specification_version: 4
170
169
  summary: Return associations and policies with API responses
171
170
  test_files: []