rest-api-generator 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -1
  3. data/Gemfile.lock +191 -43
  4. data/README.md +173 -7
  5. data/Rakefile +1 -1
  6. data/lib/generators/rest_api_generator/helpers.rb +72 -0
  7. data/lib/generators/rest_api_generator/resource_generator.rb +33 -16
  8. data/lib/generators/rest_api_generator/spec/rspec_generator.rb +36 -0
  9. data/lib/generators/rest_api_generator/spec/rswag_generator.rb +54 -0
  10. data/lib/generators/rest_api_generator/spec/templates/rspec/nested_resource_controller_spec.rb.tt +62 -0
  11. data/lib/generators/rest_api_generator/{templates/rest_api_spec.rb.tt → spec/templates/rspec/resource_controller_spec.rb.tt} +5 -5
  12. data/lib/generators/rest_api_generator/spec/templates/rswag/nested_resource_controller_spec.rb.tt +116 -0
  13. data/lib/generators/rest_api_generator/spec/templates/rswag/resource_controller_spec.rb.tt +111 -0
  14. data/lib/generators/rest_api_generator/templates/child_api_controller.rb.tt +10 -9
  15. data/lib/generators/rest_api_generator/templates/implicit_child_resource_controller.rb.tt +4 -0
  16. data/lib/generators/rest_api_generator/templates/implicit_resource_controller.rb.tt +4 -0
  17. data/lib/generators/rest_api_generator/templates/rest_api_controller.rb.tt +2 -0
  18. data/lib/rest-api-generator.rb +3 -0
  19. data/lib/rest_api_generator/application_controller.rb +8 -0
  20. data/lib/rest_api_generator/child_resource_controller.rb +97 -0
  21. data/lib/rest_api_generator/filterable.rb +30 -0
  22. data/lib/rest_api_generator/helpers/render.rb +1 -1
  23. data/lib/rest_api_generator/orderable.rb +30 -0
  24. data/lib/rest_api_generator/resource_controller.rb +73 -0
  25. data/lib/rest_api_generator/version.rb +1 -1
  26. data/lib/rest_api_generator.rb +11 -1
  27. data/rest-api-generator.gemspec +11 -4
  28. metadata +90 -8
  29. data/lib/generators/rest_api_generator/templates/child_api_spec.rb.tt +0 -59
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module RestApiGenerator
6
+ module Filterable
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ @filter_scopes ||= []
11
+ end
12
+
13
+ module ClassMethods
14
+ attr_reader :filter_scopes
15
+
16
+ def filter_scope(name, *args)
17
+ scope name, *args
18
+ @filter_scopes << name.to_s.gsub("filter_by_", "").to_sym
19
+ end
20
+
21
+ def filter_resource(params)
22
+ results = where(nil)
23
+ params.each do |key, value|
24
+ results = results.public_send("filter_by_#{key}", value) if value.present?
25
+ end
26
+ results
27
+ end
28
+ end
29
+ end
30
+ end
@@ -7,7 +7,7 @@ module RestApiGenerator
7
7
  {
8
8
  status: status,
9
9
  error: error,
10
- message: message
10
+ message: message,
11
11
  }.as_json
12
12
  end
13
13
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+ require "active_support/concern"
5
+
6
+ module RestApiGenerator
7
+ module Orderable
8
+ extend ActiveSupport::Concern
9
+
10
+ SORT_ORDER = { " " => :asc, "+" => :asc, "-" => :desc }
11
+
12
+ # Returns params for order in active record order syntax
13
+ # GET /api/v1/transactions?sort=-amount
14
+ #
15
+ # ordering_params(params) # => { amount: :desc }
16
+ def ordering_params(order_params)
17
+ ordering = {}
18
+ if order_params
19
+ sorted_params = order_params.split(",")
20
+ sorted_params.each do |attr|
21
+ sort_sign = /\A[ +-]/.match?(attr) ? attr.slice!(0) : "+"
22
+ if resource_class.attribute_names.include?(attr)
23
+ ordering[attr] = SORT_ORDER[sort_sign]
24
+ end
25
+ end
26
+ end
27
+ ordering
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RestApiGenerator
4
+ class ResourceController < RestApiGenerator.parent_controller.constantize
5
+ include Orderable
6
+
7
+ before_action :set_resource, only: [:show, :update, :destroy]
8
+
9
+ def index
10
+ @resources = resource_class.all
11
+ @resources = @resources.filter_resource(params_for_filter) if resource_class.include?(Filterable)
12
+ @resources = @resources.order(ordering_params(params[:sort])) if params[:sort]
13
+ render json: @resources, status: :ok
14
+ end
15
+
16
+ def show
17
+ render json: @resource, status: :ok
18
+ end
19
+
20
+ def create
21
+ @resource = resource_class.create!(resource_created_params)
22
+ render json: @resource, status: :created
23
+ end
24
+
25
+ def update
26
+ @resource.update!(resource_updated_params)
27
+ render json: @resource, status: :ok
28
+ end
29
+
30
+ def destroy
31
+ @resource.destroy!
32
+ end
33
+
34
+ private
35
+
36
+ def params_for_filter
37
+ params.slice(*resource_class.filter_scopes)
38
+ end
39
+
40
+ def resource_class
41
+ resource_by_controller_name
42
+ end
43
+
44
+ def resource_created_params
45
+ resource_params
46
+ end
47
+
48
+ def resource_updated_params
49
+ resource_params
50
+ end
51
+
52
+ def resource_params
53
+ params.require(resource_class.model_name.singular.to_sym).permit(resource_attributes)
54
+ end
55
+
56
+ def resource_attributes
57
+ resource_class.attribute_names.map(&:to_sym)
58
+ end
59
+
60
+ def set_resource
61
+ @resource = resource_class.find(record_id)
62
+ end
63
+
64
+ # UsersController => User
65
+ def resource_by_controller_name(controller_name = self.class.to_s)
66
+ controller_name.split(Regexp.union(["Controller", "::"]))[-1].singularize.constantize
67
+ end
68
+
69
+ def record_id
70
+ params.permit(:id)[:id]
71
+ end
72
+ end
73
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RestApiGenerator
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
@@ -1,11 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rails"
3
4
  require_relative "rest_api_generator/version"
5
+ require_relative "rest_api_generator/application_controller"
4
6
  require_relative "rest_api_generator/error_handler"
5
7
  require_relative "rest_api_generator/custom_error"
6
8
  require_relative "rest_api_generator/helpers/render"
9
+ require_relative "rest_api_generator/filterable"
10
+ require_relative "rest_api_generator/orderable"
7
11
 
8
12
  module RestApiGenerator
9
13
  class Error < StandardError; end
10
- # Your code goes here...
14
+
15
+ def self.parent_controller
16
+ "RestApiGenerator::ApplicationController"
17
+ end
11
18
  end
19
+
20
+ require_relative "rest_api_generator/resource_controller"
21
+ require_relative "rest_api_generator/child_resource_controller"
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ $LOAD_PATH.push File.expand_path("../lib", __FILE__)
4
+
3
5
  require_relative "lib/rest_api_generator/version"
4
- require_relative "lib/rest_api_generator"
5
6
 
6
7
  Gem::Specification.new do |spec|
7
8
  spec.name = "rest-api-generator"
@@ -22,14 +23,20 @@ Gem::Specification.new do |spec|
22
23
  spec.metadata["changelog_uri"] = "https://github.com/SwitchDreams/rest-api-generator"
23
24
 
24
25
  spec.files = Dir["{bin,sig,lib,public}/**/*", "MIT-LICENSE", "Rakefile", "README.md", "rest-api-generator.gemspec",
25
- "Gemfile", "Gemfile.lock"]
26
+ "Gemfile", "Gemfile.lock"]
26
27
  spec.bindir = "exe"
27
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
29
  spec.require_paths = ["lib"]
29
30
 
30
- spec.add_runtime_dependency("railties", ">= 5.0.0")
31
-
32
31
  # For more information and examples about making a new gem, check out our
33
32
  # guide at: https://bundler.io/guides/creating_gem.html
34
33
  spec.metadata["rubygems_mfa_required"] = "true"
34
+
35
+ spec.add_dependency "rails", ">= 5.0"
36
+
37
+ spec.add_development_dependency "ammeter", "~> 1.1.5"
38
+ spec.add_development_dependency "database_cleaner"
39
+ spec.add_development_dependency "rspec-rails", "~> 6.0.0"
40
+ spec.add_development_dependency "rswag"
41
+ spec.add_development_dependency "rswag-specs"
35
42
  end
metadata CHANGED
@@ -1,29 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-api-generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - PedroAugustoRamalhoDuarte
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-07 00:00:00.000000000 Z
11
+ date: 2023-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: railties
14
+ name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.0
19
+ version: '5.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 5.0.0
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ammeter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.5
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.5
41
+ - !ruby/object:Gem::Dependency
42
+ name: database_cleaner
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 6.0.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 6.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rswag
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rswag-specs
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
27
97
  description: This gem helps you to build a Ruby on Rails REST API faster, using a
28
98
  scaffold-like generator that follows the best practices.
29
99
  email:
@@ -41,14 +111,26 @@ files:
41
111
  - lib/generators/rest_api_generator/USAGE
42
112
  - lib/generators/rest_api_generator/helpers.rb
43
113
  - lib/generators/rest_api_generator/resource_generator.rb
114
+ - lib/generators/rest_api_generator/spec/rspec_generator.rb
115
+ - lib/generators/rest_api_generator/spec/rswag_generator.rb
116
+ - lib/generators/rest_api_generator/spec/templates/rspec/nested_resource_controller_spec.rb.tt
117
+ - lib/generators/rest_api_generator/spec/templates/rspec/resource_controller_spec.rb.tt
118
+ - lib/generators/rest_api_generator/spec/templates/rswag/nested_resource_controller_spec.rb.tt
119
+ - lib/generators/rest_api_generator/spec/templates/rswag/resource_controller_spec.rb.tt
44
120
  - lib/generators/rest_api_generator/templates/child_api_controller.rb.tt
45
- - lib/generators/rest_api_generator/templates/child_api_spec.rb.tt
121
+ - lib/generators/rest_api_generator/templates/implicit_child_resource_controller.rb.tt
122
+ - lib/generators/rest_api_generator/templates/implicit_resource_controller.rb.tt
46
123
  - lib/generators/rest_api_generator/templates/rest_api_controller.rb.tt
47
- - lib/generators/rest_api_generator/templates/rest_api_spec.rb.tt
124
+ - lib/rest-api-generator.rb
48
125
  - lib/rest_api_generator.rb
126
+ - lib/rest_api_generator/application_controller.rb
127
+ - lib/rest_api_generator/child_resource_controller.rb
49
128
  - lib/rest_api_generator/custom_error.rb
50
129
  - lib/rest_api_generator/error_handler.rb
130
+ - lib/rest_api_generator/filterable.rb
51
131
  - lib/rest_api_generator/helpers/render.rb
132
+ - lib/rest_api_generator/orderable.rb
133
+ - lib/rest_api_generator/resource_controller.rb
52
134
  - lib/rest_api_generator/version.rb
53
135
  - rest-api-generator.gemspec
54
136
  - sig/rest_api_generator.rbs
@@ -76,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
158
  - !ruby/object:Gem::Version
77
159
  version: '0'
78
160
  requirements: []
79
- rubygems_version: 3.3.3
161
+ rubygems_version: 3.3.7
80
162
  signing_key:
81
163
  specification_version: 4
82
164
  summary: Build a Ruby on Rails REST API faster
@@ -1,59 +0,0 @@
1
- require 'rails_helper'
2
-
3
- RSpec.describe "<%=class_name %>", type: :request do
4
- let(:valid_attributes) { attributes_for(:<%= singular_table_name %>) }
5
-
6
- describe "POST /<%= plural_name%>" do
7
- context "with valid parameters" do
8
- it "creates a new <%=singular_name %>" do
9
- <%= options['scope'].downcase %> = create(:<%= options['scope'].downcase %>)
10
- expect do
11
- post "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%= plural_name %>",
12
- params: { <%= singular_name %>: valid_attributes }
13
- end.to change(<%= class_name %>, :count).by(1)
14
- end
15
- end
16
- end
17
-
18
- describe "PATCH /<%= plural_name %>" do
19
- let(:<%= options['scope'].downcase %>) {create(:<%= options['scope'].downcase %>)}
20
- let(:<%= singular_table_name %>) { create(:<%=singular_table_name %>, <%= options['scope'].downcase %>: <%= options['scope'].downcase %>)}
21
-
22
- it "updates an <%=singular_name %>" do
23
- patch "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%=plural_name %>/#{<%= singular_name %>.id}",
24
- params: { <%= singular_name %>: valid_attributes }
25
- expect(response).to have_http_status(:success)
26
- end
27
- end
28
-
29
- describe "DELETE /<%= singular_name %>" do
30
- let(:<%= options['scope'].downcase %>) {create(:<%= options['scope'].downcase %>)}
31
-
32
- it "deletes an <%=singular_name %>" do
33
- <%= singular_table_name %> = create(:<%=singular_table_name %>, <%= options['scope'].downcase %>: <%= options['scope'].downcase %>)
34
- expect do
35
- delete "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%=plural_name %>/#{<%= singular_name %>.id}"
36
- end.to change(<%= class_name %>, :count).by(-1)
37
- end
38
- end
39
-
40
- describe "GET/ <%= singular_name %>" do
41
- let(:<%= options['scope'].downcase %>) {create(:<%= options['scope'].downcase %>)}
42
- let(:<%= singular_table_name %>) { create(:<%=singular_table_name %>, <%= options['scope'].downcase %>: <%= options['scope'].downcase %>)}
43
-
44
- it "gets an <%=singular_name %>" do
45
- get "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%= plural_name %>/#{<%= singular_name %>.id}"
46
- expect(response).to be_successful
47
- end
48
- end
49
-
50
- describe "GET /<%= plural_name %>" do
51
- let(:<%= options['scope'].downcase %>) {create(:<%= options['scope'].downcase %>)}
52
- let(:<%= singular_table_name %>) { create(:<%=singular_table_name %>, <%= options['scope'].downcase %>: <%= options['scope'].downcase %>) }
53
-
54
- it "renders a successful response" do
55
- get "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%= plural_name %>"
56
- expect(response).to be_successful
57
- end
58
- end
59
- end