api_me 0.3.2 → 0.3.3
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 +4 -4
- data/.rubocop.yml +8 -0
- data/.ruby-version +1 -1
- data/README.md +12 -3
- data/lib/api_me.rb +5 -5
- data/lib/api_me/base_filter.rb +1 -1
- data/lib/api_me/version.rb +1 -1
- data/lib/generators/api_me/controller/controller_generator.rb +7 -6
- data/lib/generators/api_me/filter/filter_generator.rb +4 -4
- data/lib/generators/api_me/install_generator.rb +9 -0
- data/lib/generators/api_me/policy/policy_generator.rb +4 -4
- data/spec/acceptance/api/v1/posts_spec.rb +12 -10
- data/spec/acceptance/api/v1/users_spec.rb +5 -3
- data/spec/acceptance/multi_word_resource_spec.rb +2 -2
- data/spec/internal/app/controllers/api/v1/fails_controller.rb +1 -1
- data/spec/internal/app/controllers/api/v1/multi_word_resources_controller.rb +1 -1
- data/spec/internal/app/controllers/api/v1/posts_controller.rb +1 -1
- data/spec/internal/app/controllers/api/v1/users_controller.rb +1 -1
- data/spec/internal/app/filters/user_filter.rb +1 -1
- data/spec/internal/app/models/test_model.rb +2 -2
- data/spec/internal/app/serializers/test_model_serializer.rb +2 -4
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80f808a1b1be8921cfa450b223aff0973bd6871b
|
4
|
+
data.tar.gz: 8bb0c02b197eafbe2d523182b3261a2193d4ee09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10f743c5668ce8030571c14d0a5b38cb98ab4208f7c6bd2e63834538390ba29d2e541e6764d949a7c963a5293fd94c6490b49530cc6ce1c179297af285ac7feb
|
7
|
+
data.tar.gz: e19dcdb213864572ff53710f83b36aa69d7c3f48590a08b71e44305f3c6d7a2228a0dcc0a360cfe49933d52e19045a74547708e4e66f81c0cb168129b63de784
|
data/.rubocop.yml
ADDED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.4
|
data/README.md
CHANGED
@@ -10,10 +10,19 @@ ApiMe provides a set of generators and base classes to assist with building Rest
|
|
10
10
|
### Details
|
11
11
|
Api controllers use the fantastic [Pundit](https://github.com/elabs/pundit) gem for authorization and parameter whitelisting, [Active Model Serializers ver 0.8](https://github.com/rails-api/active_model_serializers/tree/0-8-stable) for resource serialization, and [SearchObject](https://github.com/RStankov/SearchObject) for list filtering. The model, filter, serializer, and policy that the controller uses by default can all be overriden, along with other optional parameters.
|
12
12
|
|
13
|
-
The primary goal of this gem was to keep things simple so that customization is fairly straight forward
|
13
|
+
The primary goal of this gem was to keep things simple so that customization is fairly straight forward by separating concerns and providing overrides. Reusing existing libraries was a primary goal during the design, hence the overall simplicity of this gem. We currently use this gem internally at [Inigo](inigo.io) and are committed to its ongoing maintenance.
|
14
|
+
|
15
|
+
### Installation
|
16
|
+
Add the gem to your Gemfile: `gem api_me`.
|
17
|
+
|
18
|
+
Run `bundle install` to install it.
|
19
|
+
|
20
|
+
Run `rails generate api_me:install` to install api_me.
|
21
|
+
|
22
|
+
You are now setup!
|
14
23
|
|
15
24
|
### Usage
|
16
|
-
`rails
|
25
|
+
`rails generate api_me:resource user organization:belongs_to name:string ...`
|
17
26
|
|
18
27
|
this generates the following:
|
19
28
|
|
@@ -22,7 +31,7 @@ this generates the following:
|
|
22
31
|
* app/serializers/user_serializer.rb
|
23
32
|
|
24
33
|
and also essentially calls:
|
25
|
-
* `rails
|
34
|
+
* `rails generate model user organization:belongs_to name:string ...`
|
26
35
|
Which generates the model et al as specified.
|
27
36
|
|
28
37
|
users_controller.rb:
|
data/lib/api_me.rb
CHANGED
@@ -14,11 +14,11 @@ module ApiMe
|
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
17
|
-
def model(klass)
|
17
|
+
def model(klass) # rubocop:disable TrivialAccessors
|
18
18
|
@model_klass = klass
|
19
19
|
end
|
20
20
|
|
21
|
-
def serializer(klass)
|
21
|
+
def serializer(klass) # rubocop:disable TrivialAccessors
|
22
22
|
@serializer_klass = klass
|
23
23
|
end
|
24
24
|
|
@@ -62,12 +62,12 @@ module ApiMe
|
|
62
62
|
# the top level ids array param. Would eventually like
|
63
63
|
# to move to support the jsonapi.org standard closer.
|
64
64
|
def index
|
65
|
-
ids_filter_hash = params[:ids] ? {ids: params[:ids]} : {}
|
65
|
+
ids_filter_hash = params[:ids] ? { ids: params[:ids] } : {}
|
66
66
|
@scoped_objects = policy_scope(model_klass.all)
|
67
|
-
@filter_objects = filter_klass.new(
|
67
|
+
@filter_objects = filter_klass.new(
|
68
68
|
scope: @scoped_objects,
|
69
69
|
filters: (filter_params || {}).merge(ids_filter_hash)
|
70
|
-
|
70
|
+
)
|
71
71
|
|
72
72
|
render json: @filter_objects.results, each_serializer: serializer_klass
|
73
73
|
end
|
data/lib/api_me/base_filter.rb
CHANGED
data/lib/api_me/version.rb
CHANGED
@@ -26,7 +26,9 @@ module ApiMe
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def controller_class_name
|
29
|
-
"#{controllers_namespace.capitalize}
|
29
|
+
"#{controllers_namespace.capitalize}::"\
|
30
|
+
"#{controllers_api_version.capitalize}::"\
|
31
|
+
"#{plural_name.camelize}Controller"
|
30
32
|
end
|
31
33
|
|
32
34
|
def attributes_names
|
@@ -39,14 +41,14 @@ module ApiMe
|
|
39
41
|
|
40
42
|
def nonpolymorphic_attribute_names
|
41
43
|
associations.select { |attr| attr.type.in?([:belongs_to, :references]) }
|
42
|
-
|
43
|
-
|
44
|
+
.reject { |attr| attr.attr_options.fetch(:polymorphic, false) }
|
45
|
+
.map { |attr| "#{attr.name}_id".to_sym }
|
44
46
|
end
|
45
47
|
|
46
48
|
def polymorphic_attribute_names
|
47
49
|
associations.select { |attr| attr.type.in?([:belongs_to, :references]) }
|
48
|
-
|
49
|
-
|
50
|
+
.select { |attr| attr.attr_options.fetch(:polymorphic, false) }
|
51
|
+
.map { |attr| ["#{attr.name}_id".to_sym, "#{attr.name}_type".to_sym] }.flatten
|
50
52
|
end
|
51
53
|
|
52
54
|
def association_attribute_names
|
@@ -58,7 +60,6 @@ module ApiMe
|
|
58
60
|
end
|
59
61
|
|
60
62
|
def parent_class_name
|
61
|
-
base_controller_name = "#{controllers_namespace.capitalize}::BaseController"
|
62
63
|
if options[:parent]
|
63
64
|
options[:parent]
|
64
65
|
else
|
@@ -26,14 +26,14 @@ module ApiMe
|
|
26
26
|
|
27
27
|
def nonpolymorphic_attribute_names
|
28
28
|
associations.select { |attr| attr.type.in?([:belongs_to, :references]) }
|
29
|
-
|
30
|
-
|
29
|
+
.reject { |attr| attr.attr_options.fetch(:polymorphic, false) }
|
30
|
+
.map { |attr| "#{attr.name}_id".to_sym }
|
31
31
|
end
|
32
32
|
|
33
33
|
def polymorphic_attribute_names
|
34
34
|
associations.select { |attr| attr.type.in?([:belongs_to, :references]) }
|
35
|
-
|
36
|
-
|
35
|
+
.select { |attr| attr.attr_options.fetch(:polymorphic, false) }
|
36
|
+
.map { |attr| ["#{attr.name}_id".to_sym, "#{attr.name}_type".to_sym] }.flatten
|
37
37
|
end
|
38
38
|
|
39
39
|
def association_attribute_names
|
@@ -26,14 +26,14 @@ module ApiMe
|
|
26
26
|
|
27
27
|
def nonpolymorphic_attribute_names
|
28
28
|
associations.select { |attr| attr.type.in?([:belongs_to, :references]) }
|
29
|
-
|
30
|
-
|
29
|
+
.reject { |attr| attr.attr_options.fetch(:polymorphic, false) }
|
30
|
+
.map { |attr| "#{attr.name}_id".to_sym }
|
31
31
|
end
|
32
32
|
|
33
33
|
def polymorphic_attribute_names
|
34
34
|
associations.select { |attr| attr.type.in?([:belongs_to, :references]) }
|
35
|
-
|
36
|
-
|
35
|
+
.select { |attr| attr.attr_options.fetch(:polymorphic, false) }
|
36
|
+
.map { |attr| ["#{attr.name}_id".to_sym, "#{attr.name}_type".to_sym] }.flatten
|
37
37
|
end
|
38
38
|
|
39
39
|
def association_attribute_names
|
@@ -3,8 +3,8 @@ require 'spec_helper'
|
|
3
3
|
describe 'Users API' do
|
4
4
|
it 'sends the list of posts using the default filter' do
|
5
5
|
posts = [
|
6
|
-
Post.create(name:
|
7
|
-
Post.create(name:
|
6
|
+
Post.create(name: 'test'),
|
7
|
+
Post.create(name: 'test 2')
|
8
8
|
]
|
9
9
|
|
10
10
|
get '/api/v1/posts'
|
@@ -12,22 +12,24 @@ describe 'Users API' do
|
|
12
12
|
expect(last_response.status).to eq(200)
|
13
13
|
json = JSON.parse(last_response.body)
|
14
14
|
|
15
|
-
expect(json['posts'].length).to eq(
|
15
|
+
expect(json['posts'].length).to eq(posts.count)
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'sends posts filtered by ids' do
|
19
|
-
|
20
|
-
Post.create(name:
|
21
|
-
Post.create(name:
|
22
|
-
Post.create(name:
|
19
|
+
all_posts = [
|
20
|
+
Post.create(name: 'test'),
|
21
|
+
Post.create(name: 'test 2'),
|
22
|
+
Post.create(name: 'test 3')
|
23
23
|
]
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
filtered_posts = [all_posts[0], all_posts[2]]
|
26
|
+
|
27
|
+
get '/api/v1/posts?ids%5B%5D=' + filtered_posts[0].id.to_s +
|
28
|
+
'&ids%5B%5D=' + filtered_posts[1].id.to_s
|
27
29
|
|
28
30
|
expect(last_response.status).to eq(200)
|
29
31
|
json = JSON.parse(last_response.body)
|
30
32
|
|
31
|
-
expect(json['posts'].length).to eq(
|
33
|
+
expect(json['posts'].length).to eq(filtered_posts.count)
|
32
34
|
end
|
33
35
|
end
|
@@ -12,7 +12,7 @@ describe 'Users API' do
|
|
12
12
|
expect(last_response.status).to eq(200)
|
13
13
|
json = JSON.parse(last_response.body)
|
14
14
|
|
15
|
-
expect(json['users'].length).to eq(
|
15
|
+
expect(json['users'].length).to eq(users.count)
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'sends an individual user' do
|
@@ -64,17 +64,19 @@ describe 'Users API' do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'sends a filtered list of users' do
|
67
|
-
|
67
|
+
all_users = [
|
68
68
|
User.create(username: 'Test'),
|
69
69
|
User.create(username: 'Demo'),
|
70
70
|
User.create(username: 'Test 2')
|
71
71
|
]
|
72
72
|
|
73
|
+
filtered_users = [all_users[0], all_users[2]]
|
74
|
+
|
73
75
|
get '/api/v1/users?filters%5Bsearch%5D=Test'
|
74
76
|
|
75
77
|
expect(last_response.status).to eq(200)
|
76
78
|
json = JSON.parse(last_response.body)
|
77
79
|
|
78
|
-
expect(json['users'].length).to eq(
|
80
|
+
expect(json['users'].length).to eq(filtered_users.count)
|
79
81
|
end
|
80
82
|
end
|
@@ -2,11 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'multi-word API resource' do
|
4
4
|
it 'succeeds creating a new object using a resource that consists of multiple words' do
|
5
|
-
post '/api/v1/multi_word_resources',
|
5
|
+
post '/api/v1/multi_word_resources', test_model: { test: true }
|
6
6
|
|
7
7
|
expect(last_response.status).to eq(201)
|
8
8
|
json = JSON.parse(last_response.body)
|
9
9
|
|
10
|
-
expect(json['test_model'][
|
10
|
+
expect(json['test_model']['created']).to eq(true)
|
11
11
|
end
|
12
12
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_me
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Clopton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -159,6 +159,7 @@ extensions: []
|
|
159
159
|
extra_rdoc_files: []
|
160
160
|
files:
|
161
161
|
- ".gitignore"
|
162
|
+
- ".rubocop.yml"
|
162
163
|
- ".ruby-version"
|
163
164
|
- ".travis.yml"
|
164
165
|
- Gemfile
|
@@ -176,6 +177,7 @@ files:
|
|
176
177
|
- lib/generators/api_me/filter/USAGE
|
177
178
|
- lib/generators/api_me/filter/filter_generator.rb
|
178
179
|
- lib/generators/api_me/filter/templates/filter.rb
|
180
|
+
- lib/generators/api_me/install_generator.rb
|
179
181
|
- lib/generators/api_me/policy/USAGE
|
180
182
|
- lib/generators/api_me/policy/policy_generator.rb
|
181
183
|
- lib/generators/api_me/policy/templates/policy.rb
|