api_me 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|