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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 92daadad80db70e8aef932f76f51c4588438af3f
4
- data.tar.gz: 7a206ff30375d224b053b2c522fe224d130be1f1
3
+ metadata.gz: 80f808a1b1be8921cfa450b223aff0973bd6871b
4
+ data.tar.gz: 8bb0c02b197eafbe2d523182b3261a2193d4ee09
5
5
  SHA512:
6
- metadata.gz: 900a7acabcbbc6fe0ca576c7f94cb1be4e2acfc4a63d85209dacd78603dae7273aca01e6b8ae8acccdc5a95db43ef057aaef714b651013fc9347c7df864e5a5b
7
- data.tar.gz: 09053b626b1c8120569ba25202356db997985e1f79bedc01ae770af1b78d3e5dcc7caca4f9fac2279d14ff9a6406f92e7a5fd48330906d689e7d478bd7d23d0a
6
+ metadata.gz: 10f743c5668ce8030571c14d0a5b38cb98ab4208f7c6bd2e63834538390ba29d2e541e6764d949a7c963a5293fd94c6490b49530cc6ce1c179297af285ac7feb
7
+ data.tar.gz: e19dcdb213864572ff53710f83b36aa69d7c3f48590a08b71e44305f3c6d7a2228a0dcc0a360cfe49933d52e19045a74547708e4e66f81c0cb168129b63de784
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ AllCops:
2
+ Exclude:
3
+ - '**/templates/*'
4
+ - '*.gemspec'
5
+ LineLength:
6
+ Max: 100
7
+ Documentation:
8
+ Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.1.3
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 through the separating concerns and 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.
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 g api_me:resource user organization:belongs_to name:string ...`
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 g model user organization:belongs_to name:string ...`
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
@@ -2,6 +2,6 @@ module ApiMe
2
2
  class BaseFilter
3
3
  include SearchObject.module
4
4
 
5
- option(:ids) { |scope, value| scope.where("id" => value) }
5
+ option(:ids) { |scope, value| scope.where('id' => value) }
6
6
  end
7
7
  end
@@ -1,3 +1,3 @@
1
1
  module ApiMe
2
- VERSION = '0.3.2'
2
+ VERSION = '0.3.3'
3
3
  end
@@ -26,7 +26,9 @@ module ApiMe
26
26
  end
27
27
 
28
28
  def controller_class_name
29
- "#{controllers_namespace.capitalize}::#{controllers_api_version.capitalize}::#{plural_name.camelize}Controller"
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
- .reject { |attr| attr.attr_options.fetch(:polymorphic, false) }
43
- .map { |attr| "#{attr.name}_id".to_sym }
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
- .select { |attr| attr.attr_options.fetch(:polymorphic, false) }
49
- .map { |attr| ["#{attr.name}_id".to_sym, "#{attr.name}_type".to_sym] }.flatten
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
- .reject { |attr| attr.attr_options.fetch(:polymorphic, false) }
30
- .map { |attr| "#{attr.name}_id".to_sym }
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
- .select { |attr| attr.attr_options.fetch(:polymorphic, false) }
36
- .map { |attr| ["#{attr.name}_id".to_sym, "#{attr.name}_type".to_sym] }.flatten
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
@@ -0,0 +1,9 @@
1
+ module ApiMe
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ def run_generators
5
+ run 'rails g pundit:install'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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
- .reject { |attr| attr.attr_options.fetch(:polymorphic, false) }
30
- .map { |attr| "#{attr.name}_id".to_sym }
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
- .select { |attr| attr.attr_options.fetch(:polymorphic, false) }
36
- .map { |attr| ["#{attr.name}_id".to_sym, "#{attr.name}_type".to_sym] }.flatten
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: "test"),
7
- Post.create(name: "test 2")
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(2)
15
+ expect(json['posts'].length).to eq(posts.count)
16
16
  end
17
17
 
18
18
  it 'sends posts filtered by ids' do
19
- posts = [
20
- Post.create(name: "test"),
21
- Post.create(name: "test 2"),
22
- Post.create(name: "test 3")
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
- get '/api/v1/posts?ids%5B%5D=' + posts[0].id.to_s +
26
- '&ids%5B%5D=' + posts[2].id.to_s
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(2)
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(2)
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
- users = [
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(2)
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', {test_model: {test: true}}
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']["created"]).to eq(true)
10
+ expect(json['test_model']['created']).to eq(true)
11
11
  end
12
12
  end
@@ -1,4 +1,4 @@
1
- class Api::V1::FailsController < ApplicationController
1
+ class Api::V1::FailsController < ApplicationController # rubocop:disable ClassAndModuleChildren
2
2
  include ApiMe
3
3
 
4
4
  before_action :fail
@@ -1,4 +1,4 @@
1
- class Api::V1::MultiWordResourcesController < ApplicationController
1
+ class Api::V1::MultiWordResourcesController < ApplicationController # rubocop:disable ClassAndModuleChildren, LineLength
2
2
  include ApiMe
3
3
 
4
4
  model TestModel
@@ -1,3 +1,3 @@
1
- class Api::V1::PostsController < ApplicationController
1
+ class Api::V1::PostsController < ApplicationController # rubocop:disable ClassAndModuleChildren
2
2
  include ApiMe
3
3
  end
@@ -1,3 +1,3 @@
1
- class Api::V1::UsersController < ApplicationController
1
+ class Api::V1::UsersController < ApplicationController # rubocop:disable ClassAndModuleChildren
2
2
  include ApiMe
3
3
  end
@@ -3,5 +3,5 @@ require 'search_object'
3
3
  class UserFilter < ApiMe::BaseFilter
4
4
  include ::SearchObject.module
5
5
 
6
- option(:search) { |scope, value| scope.where("username LIKE ?", "%#{value}%") }
6
+ option(:search) { |scope, value| scope.where('username LIKE ?', "%#{value}%") }
7
7
  end
@@ -7,10 +7,10 @@ class TestModel
7
7
  @created ||= false
8
8
  end
9
9
 
10
- def initialize(*args)
10
+ def initialize(*_args)
11
11
  end
12
12
 
13
- def save!(*args)
13
+ def save!(*_args)
14
14
  TestModel.create
15
15
  end
16
16
 
@@ -1,7 +1,5 @@
1
1
  class TestModelSerializer < ActiveModel::Serializer
2
2
  attributes :created
3
-
4
- def created
5
- object.created
6
- end
3
+
4
+ delegate :created, to: :object
7
5
  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.2
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-10 00:00:00.000000000 Z
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