rest-api-generator 0.1.1 → 0.1.2

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
  SHA256:
3
- metadata.gz: f3e06c4a9026a2a814873ee73588d2192c5962d366f35bf6dfd4277208887abd
4
- data.tar.gz: e4efc771085f7fafb99399ddaa899ff72edf90865d5bd03f39644e686b841c48
3
+ metadata.gz: cf4062a70bed1e9006d96375d4110b3918f3bf5d074304c4619abfa4fe33eb03
4
+ data.tar.gz: ba52d11b288dd8004e68327a8db4aabac8bef8be93eea85382f3bf349406ea39
5
5
  SHA512:
6
- metadata.gz: 633346498caa5fa13db9077962e5a26d1015764f60c96aac91ba75f712f483cba833a16323c19a84f20f91d93c1fbf02ecd2028f59998f4388b151cd41b02db9
7
- data.tar.gz: 6584c32a008736381fb3b5658cbf21b69efb4587a570d78143a4658ef3c98c4e72049b05e8ebee8453bed60ff6bc559d3a37ca24026d97e5f17537d1ee41a58c
6
+ metadata.gz: a1ef3d60ca714e5edf5db7cdcf6b0287ef22c2123c907070cb3b6608ca159ceba200642a8b45894cb88e0fab73d5abaeb728e19a05c9e2760cd0e17ccb155732
7
+ data.tar.gz: 9849fa88d3b3a9f5a070c7f4a4ca29fc3deb8447adb80260004aa68076cd0a27db9cbeb5d214aed2505df4a1c1a48e26378dc41b6626159eb635d1a7d2c0218e
data/Gemfile CHANGED
@@ -9,4 +9,4 @@ gem "rake", "~> 13.0"
9
9
 
10
10
  gem "rspec", "~> 3.0"
11
11
 
12
- gem "rubocop", "~> 1.21"
12
+ gem "switchcop"
data/Gemfile.lock CHANGED
@@ -1,107 +1,234 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rest-api-generator (0.1.1)
5
- railties (>= 5.0.0)
4
+ rest-api-generator (0.1.2)
5
+ rails (>= 5.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- actionpack (6.1.6)
11
- actionview (= 6.1.6)
12
- activesupport (= 6.1.6)
13
- rack (~> 2.0, >= 2.0.9)
10
+ actioncable (7.0.4)
11
+ actionpack (= 7.0.4)
12
+ activesupport (= 7.0.4)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailbox (7.0.4)
16
+ actionpack (= 7.0.4)
17
+ activejob (= 7.0.4)
18
+ activerecord (= 7.0.4)
19
+ activestorage (= 7.0.4)
20
+ activesupport (= 7.0.4)
21
+ mail (>= 2.7.1)
22
+ net-imap
23
+ net-pop
24
+ net-smtp
25
+ actionmailer (7.0.4)
26
+ actionpack (= 7.0.4)
27
+ actionview (= 7.0.4)
28
+ activejob (= 7.0.4)
29
+ activesupport (= 7.0.4)
30
+ mail (~> 2.5, >= 2.5.4)
31
+ net-imap
32
+ net-pop
33
+ net-smtp
34
+ rails-dom-testing (~> 2.0)
35
+ actionpack (7.0.4)
36
+ actionview (= 7.0.4)
37
+ activesupport (= 7.0.4)
38
+ rack (~> 2.0, >= 2.2.0)
14
39
  rack-test (>= 0.6.3)
15
40
  rails-dom-testing (~> 2.0)
16
41
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
17
- actionview (6.1.6)
18
- activesupport (= 6.1.6)
42
+ actiontext (7.0.4)
43
+ actionpack (= 7.0.4)
44
+ activerecord (= 7.0.4)
45
+ activestorage (= 7.0.4)
46
+ activesupport (= 7.0.4)
47
+ globalid (>= 0.6.0)
48
+ nokogiri (>= 1.8.5)
49
+ actionview (7.0.4)
50
+ activesupport (= 7.0.4)
19
51
  builder (~> 3.1)
20
52
  erubi (~> 1.4)
21
53
  rails-dom-testing (~> 2.0)
22
54
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
23
- activesupport (6.1.6)
55
+ activejob (7.0.4)
56
+ activesupport (= 7.0.4)
57
+ globalid (>= 0.3.6)
58
+ activemodel (7.0.4)
59
+ activesupport (= 7.0.4)
60
+ activerecord (7.0.4)
61
+ activemodel (= 7.0.4)
62
+ activesupport (= 7.0.4)
63
+ activestorage (7.0.4)
64
+ actionpack (= 7.0.4)
65
+ activejob (= 7.0.4)
66
+ activerecord (= 7.0.4)
67
+ activesupport (= 7.0.4)
68
+ marcel (~> 1.0)
69
+ mini_mime (>= 1.1.0)
70
+ activesupport (7.0.4)
24
71
  concurrent-ruby (~> 1.0, >= 1.0.2)
25
72
  i18n (>= 1.6, < 2)
26
73
  minitest (>= 5.1)
27
74
  tzinfo (~> 2.0)
28
- zeitwerk (~> 2.3)
75
+ ammeter (1.1.5)
76
+ activesupport (>= 3.0)
77
+ railties (>= 3.0)
78
+ rspec-rails (>= 2.2)
29
79
  ast (2.4.2)
30
80
  builder (3.2.4)
31
81
  concurrent-ruby (1.1.10)
32
82
  crass (1.0.6)
83
+ database_cleaner (2.0.1)
84
+ database_cleaner-active_record (~> 2.0.0)
85
+ database_cleaner-active_record (2.0.1)
86
+ activerecord (>= 5.a)
87
+ database_cleaner-core (~> 2.0.0)
88
+ database_cleaner-core (2.0.1)
89
+ date (3.3.3)
33
90
  diff-lcs (1.5.0)
34
- erubi (1.10.0)
35
- i18n (1.10.0)
91
+ erubi (1.12.0)
92
+ globalid (1.0.0)
93
+ activesupport (>= 5.0)
94
+ i18n (1.12.0)
36
95
  concurrent-ruby (~> 1.0)
37
- loofah (2.18.0)
96
+ json (2.6.3)
97
+ loofah (2.19.1)
38
98
  crass (~> 1.0.2)
39
99
  nokogiri (>= 1.5.9)
100
+ mail (2.8.0)
101
+ mini_mime (>= 0.1.1)
102
+ net-imap
103
+ net-pop
104
+ net-smtp
105
+ marcel (1.0.2)
40
106
  method_source (1.0.0)
41
- minitest (5.16.1)
42
- nokogiri (1.13.6-x86_64-linux)
107
+ mini_mime (1.1.2)
108
+ minitest (5.16.3)
109
+ net-imap (0.3.4)
110
+ date
111
+ net-protocol
112
+ net-pop (0.1.2)
113
+ net-protocol
114
+ net-protocol (0.2.1)
115
+ timeout
116
+ net-smtp (0.3.3)
117
+ net-protocol
118
+ nio4r (2.5.8)
119
+ nokogiri (1.13.10-x86_64-linux)
43
120
  racc (~> 1.4)
44
121
  parallel (1.22.1)
45
- parser (3.1.2.0)
122
+ parser (3.1.3.0)
46
123
  ast (~> 2.4.1)
47
- racc (1.6.0)
124
+ racc (1.6.2)
48
125
  rack (2.2.4)
49
126
  rack-test (2.0.2)
50
127
  rack (>= 1.3)
128
+ rails (7.0.4)
129
+ actioncable (= 7.0.4)
130
+ actionmailbox (= 7.0.4)
131
+ actionmailer (= 7.0.4)
132
+ actionpack (= 7.0.4)
133
+ actiontext (= 7.0.4)
134
+ actionview (= 7.0.4)
135
+ activejob (= 7.0.4)
136
+ activemodel (= 7.0.4)
137
+ activerecord (= 7.0.4)
138
+ activestorage (= 7.0.4)
139
+ activesupport (= 7.0.4)
140
+ bundler (>= 1.15.0)
141
+ railties (= 7.0.4)
51
142
  rails-dom-testing (2.0.3)
52
143
  activesupport (>= 4.2.0)
53
144
  nokogiri (>= 1.6)
54
- rails-html-sanitizer (1.4.3)
55
- loofah (~> 2.3)
56
- railties (6.1.6)
57
- actionpack (= 6.1.6)
58
- activesupport (= 6.1.6)
145
+ rails-html-sanitizer (1.4.4)
146
+ loofah (~> 2.19, >= 2.19.1)
147
+ railties (7.0.4)
148
+ actionpack (= 7.0.4)
149
+ activesupport (= 7.0.4)
59
150
  method_source
60
151
  rake (>= 12.2)
61
152
  thor (~> 1.0)
153
+ zeitwerk (~> 2.5)
62
154
  rainbow (3.1.1)
63
155
  rake (13.0.6)
64
- regexp_parser (2.3.1)
156
+ regexp_parser (2.6.1)
65
157
  rexml (3.2.5)
66
- rspec (3.11.0)
67
- rspec-core (~> 3.11.0)
68
- rspec-expectations (~> 3.11.0)
69
- rspec-mocks (~> 3.11.0)
70
- rspec-core (3.11.0)
71
- rspec-support (~> 3.11.0)
72
- rspec-expectations (3.11.0)
158
+ rspec (3.12.0)
159
+ rspec-core (~> 3.12.0)
160
+ rspec-expectations (~> 3.12.0)
161
+ rspec-mocks (~> 3.12.0)
162
+ rspec-core (3.12.0)
163
+ rspec-support (~> 3.12.0)
164
+ rspec-expectations (3.12.1)
73
165
  diff-lcs (>= 1.2.0, < 2.0)
74
- rspec-support (~> 3.11.0)
75
- rspec-mocks (3.11.1)
166
+ rspec-support (~> 3.12.0)
167
+ rspec-mocks (3.12.1)
76
168
  diff-lcs (>= 1.2.0, < 2.0)
77
- rspec-support (~> 3.11.0)
78
- rspec-support (3.11.0)
79
- rubocop (1.28.2)
169
+ rspec-support (~> 3.12.0)
170
+ rspec-rails (6.0.1)
171
+ actionpack (>= 6.1)
172
+ activesupport (>= 6.1)
173
+ railties (>= 6.1)
174
+ rspec-core (~> 3.11)
175
+ rspec-expectations (~> 3.11)
176
+ rspec-mocks (~> 3.11)
177
+ rspec-support (~> 3.11)
178
+ rspec-support (3.12.0)
179
+ rubocop (1.40.0)
180
+ json (~> 2.3)
80
181
  parallel (~> 1.10)
81
- parser (>= 3.1.0.0)
182
+ parser (>= 3.1.2.1)
82
183
  rainbow (>= 2.2.2, < 4.0)
83
184
  regexp_parser (>= 1.8, < 3.0)
84
- rexml
85
- rubocop-ast (>= 1.17.0, < 2.0)
185
+ rexml (>= 3.2.5, < 4.0)
186
+ rubocop-ast (>= 1.23.0, < 2.0)
86
187
  ruby-progressbar (~> 1.7)
87
188
  unicode-display_width (>= 1.4.0, < 3.0)
88
- rubocop-ast (1.17.0)
189
+ rubocop-ast (1.24.0)
89
190
  parser (>= 3.1.1.0)
191
+ rubocop-performance (1.15.2)
192
+ rubocop (>= 1.7.0, < 2.0)
193
+ rubocop-ast (>= 0.4.0)
194
+ rubocop-rails (2.17.4)
195
+ activesupport (>= 4.2.0)
196
+ rack (>= 1.1)
197
+ rubocop (>= 1.33.0, < 2.0)
198
+ rubocop-rspec (2.16.0)
199
+ rubocop (~> 1.33)
200
+ rubocop-shopify (2.10.1)
201
+ rubocop (~> 1.35)
90
202
  ruby-progressbar (1.11.0)
203
+ sqlite3 (1.5.4-x86_64-linux)
204
+ switchcop (0.1.2)
205
+ rubocop (~> 1.40.0)
206
+ rubocop-performance (~> 1.15.1)
207
+ rubocop-rails (~> 2.17.3)
208
+ rubocop-rspec (~> 2.16.0)
209
+ rubocop-shopify (~> 2.10.1)
91
210
  thor (1.2.1)
92
- tzinfo (2.0.4)
211
+ timeout (0.3.1)
212
+ tzinfo (2.0.5)
93
213
  concurrent-ruby (~> 1.0)
94
- unicode-display_width (2.1.0)
95
- zeitwerk (2.6.0)
214
+ unicode-display_width (2.3.0)
215
+ websocket-driver (0.7.5)
216
+ websocket-extensions (>= 0.1.0)
217
+ websocket-extensions (0.1.5)
218
+ zeitwerk (2.6.6)
96
219
 
97
220
  PLATFORMS
98
221
  x86_64-linux
99
222
 
100
223
  DEPENDENCIES
224
+ ammeter (~> 1.1.5)
225
+ database_cleaner
101
226
  rake (~> 13.0)
102
227
  rest-api-generator!
103
228
  rspec (~> 3.0)
104
- rubocop (~> 1.21)
229
+ rspec-rails (~> 6.0.0)
230
+ sqlite3
231
+ switchcop
105
232
 
106
233
  BUNDLED WITH
107
234
  2.3.3
data/README.md CHANGED
@@ -5,7 +5,7 @@ practices.
5
5
 
6
6
  ## How it works?
7
7
 
8
- The gems use vanilla Rails generators n combination with our templates to create all the resources needed to build a
8
+ The gems use vanilla Rails generators in combination with our templates to create all the resources needed to build a
9
9
  REST API.
10
10
 
11
11
  Following [Switch Dreams's](https://www.switchdreams.com.br/]) coding practices, the controllers are built with:
@@ -16,14 +16,32 @@ Following [Switch Dreams's](https://www.switchdreams.com.br/]) coding practices,
16
16
 
17
17
  - For tests, we use RSpec and FactoryBot.
18
18
 
19
+ ## Current Features
20
+
21
+ - [Automatic rest api crud generation](#example)
22
+ - [Nested Resource](#nested-resource)
23
+ - [Modular error handler](#modular-error-handler)
24
+ - [Resource ordering](#ordering)
25
+ - [Resource filter](#filtering)
26
+
27
+ ## Next Features
28
+
29
+ - Generate nested resource end-points 🚧
30
+ - Automated documentation 🚧 https://github.com/SwitchDreams/rest-api-generator/issues/12
31
+ - Serialization https://github.com/SwitchDreams/rest-api-generator/issues/14
32
+ https://github.com/SwitchDreams/rest-api-generator/issues/11
33
+ - Pagination https://github.com/SwitchDreams/rest-api-generator/issues/15
34
+ - Integration with AVO
35
+ - Select fields
36
+ - User auth module
37
+
19
38
  ## Installation
20
39
 
21
40
  Add this line to your application's Gemfile:
22
41
 
23
42
  ```ruby
24
- group :development do
25
- gem 'rest-api-generator'
26
- end
43
+ # Build a Ruby on Rails REST API faster
44
+ gem 'rest-api-generator'
27
45
  ```
28
46
 
29
47
  And then execute:
@@ -61,13 +79,15 @@ This error handler will rescue from: `ActiveRecord::RecordNotFound`
61
79
  ### Generate Resource
62
80
 
63
81
  ```bash
64
- $ rails g rest-api-generator:resource table_name attributes
82
+ $ rails g rest_api_generator:resource table_name attributes
65
83
  ```
66
84
 
67
85
  This command will create:
68
86
 
69
87
  - **Model and Migration**: Using rails default model generator
70
- - **Controller**: A controller with index,show,create,update and destroy methods.
88
+ - **Controller**: A controller that implementes CRUD by inheritance of `RestApiGenerator::ResourceController`, or you
89
+ can use eject option for create a controller
90
+ that implements index, show, create, update and destroy methods.
71
91
  - **Specs for the created controller**
72
92
  - **Factory bot factory for created model**
73
93
  - **Routes**: with rails resources
@@ -75,11 +95,96 @@ This command will create:
75
95
  ### Example
76
96
 
77
97
  ```bash
78
- $ rails g rest-api-generator:resource car name:string color:string
98
+ $ rails g rest_api_generator:resource car name:string color:string
79
99
  ```
80
100
 
81
101
  Will generate following controller and the other files:
82
102
 
103
+ ```ruby
104
+ # app/controllers/cars_controller.rb
105
+ class CarsController < RestApiGenerator::ResourceController
106
+ end
107
+ ```
108
+
109
+ For a better experience you can override some methods from the
110
+ [default controller](https://github.com/SwitchDreams/rest-api-generator/blob/main/lib/rest_api_generator/resource_controller.rb)
111
+
112
+ ### Options
113
+
114
+ | Option | Goal | Default | Usage Example |
115
+ |--------|--------------------------------------------------------------|---------|-----------------|
116
+ | father | Generate nested resource | nil | --father Users |
117
+ | scope | Scope the resource for other route or namespace organization | nil | --scope Api::V1 |
118
+ | eject | Eject the controller to high customization | false | true |
119
+
120
+ #### Scope
121
+
122
+ In REST api one of the best practices is versioning the end-points, and you can achieve this using scope options,
123
+ example:
124
+
125
+ ```bash
126
+ # Command
127
+ rails g rest_api_generator:resource car name:string color:string --scope Api::V1
128
+ ```
129
+
130
+ ```ruby
131
+ # GET api/v1/cars
132
+ module Api::V1
133
+ class CarsController < RestApiGenerator::ResourceController
134
+ end
135
+ end
136
+ ```
137
+
138
+ For this option you need to manually setup routes, for this example:
139
+
140
+ ```ruby
141
+ # routes.rb
142
+ namespace :api do
143
+ namespace :v1 do
144
+ resources :cars
145
+ end
146
+ end
147
+ ```
148
+
149
+ #### Nested resource
150
+
151
+ In REST api sometimes we need to build a nested resource, for example when we need to get all devices from a user, for
152
+ this we have nested resource option:
153
+
154
+ ```bash
155
+ # Command
156
+ rails g rest_api_generator:resource Devices name:string color:string users:references --scope Users
157
+ ```
158
+
159
+ ```ruby
160
+ # GET users/:user_id/devices
161
+ module Users
162
+ class DevicesController < RestApiGenerator::ChildResourceController
163
+ end
164
+ end
165
+ ```
166
+
167
+ For this option you need to manually setup routes, for this example:
168
+
169
+ ```ruby
170
+ # routes.rb
171
+ resources :users do
172
+ resources :devices, controller: 'users/devices'
173
+ end
174
+ ```
175
+
176
+ Considerations:
177
+
178
+ - The children model needs to belongs_to parent model and parent model needs to have has_many children model
179
+
180
+ #### Eject
181
+
182
+ Or you can use the `eject` option for create the controller with the implemented methods:
183
+
184
+ ```bash
185
+ rails g rest_api_generator:resource car name:string color:string --eject true
186
+ ```
187
+
83
188
  ```ruby
84
189
 
85
190
  class CarsController < ApplicationController
@@ -118,9 +223,52 @@ class CarsController < ApplicationController
118
223
  params.require(:car).permit(:name, :color)
119
224
  end
120
225
  end
226
+ ```
227
+
228
+ ### Resource Features
121
229
 
230
+ #### Modular Error Handler
231
+
232
+ The error module will return a json in this following format when any active record or custom error raises.
233
+
234
+ ```json
235
+ {
236
+ "status": 422,
237
+ "error": "",
238
+ "message": ""
239
+ }
122
240
  ```
123
241
 
242
+ This is good to padronize the error handler in front-end too.
243
+
244
+ #### Ordering
245
+
246
+ For ordering use this format:
247
+
248
+ - Ordering asc: `GET /cars?sort=+name or GET /cars?sort=name`
249
+ - Ordering desc: `GET /card?sort=-name`
250
+
251
+ By default, every resource column can be the key for ordering.
252
+
253
+ #### Filtering
254
+
255
+ For filter is needed to add some scopes in Model file, example:
256
+
257
+ ```ruby
258
+ # app/models/car.rb
259
+
260
+ class Car < ApplicationRecord
261
+ include RestApiGenerator::Filterable
262
+
263
+ filter_scope :filter_by_color, ->(color) { where(color: color) }
264
+ filter_scope :filter_by_name, ->(name) { where("name LIKE ?", "%#{name}%") }
265
+ end
266
+ ```
267
+
268
+ And It's done, you can filter your index end-point:
269
+
270
+ - `GET /cars?color=blue or GET /cars?color=red&name=Ferrari`
271
+
124
272
  ## Development
125
273
 
126
274
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
data/Rakefile CHANGED
@@ -9,4 +9,4 @@ require "rubocop/rake_task"
9
9
 
10
10
  RuboCop::RakeTask.new
11
11
 
12
- task default: %i[spec rubocop]
12
+ task default: [:spec, :rubocop]
@@ -17,5 +17,35 @@ module RestApiGenerator
17
17
  Rails::Generators::GeneratedAttribute.new(column.name.to_s, column.type.to_s)
18
18
  end
19
19
  end
20
+
21
+ def option_to_path(option)
22
+ option.downcase.split("::").join("/")
23
+ end
24
+
25
+ def scope_route_path
26
+ return "" if options["scope"].blank?
27
+
28
+ option_to_path(options["scope"])
29
+ end
30
+
31
+ def nested_routes
32
+ return "" if options["father"].blank?
33
+
34
+ "#{options["father"].downcase.pluralize}/\#{#{options["father"].singularize.downcase}.id}/#{plural_name}"
35
+ end
36
+
37
+ def initial_route
38
+ scope_route_path + "/" + nested_routes
39
+ end
40
+
41
+ def spec_routes
42
+ {
43
+ index: initial_route,
44
+ show: initial_route + "\#{#{singular_name}.id}",
45
+ create: initial_route,
46
+ update: initial_route + "\#{#{singular_name}.id}",
47
+ delete: initial_route + "\#{#{singular_name}.id}",
48
+ }
49
+ end
20
50
  end
21
51
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails/generators"
4
+ require "rails/generators/active_model"
5
+ require "rails/generators/rails/model/model_generator"
4
6
  require "generators/rest_api_generator/helpers"
5
7
  module RestApiGenerator
6
8
  class ResourceGenerator < Rails::Generators::NamedBase
@@ -8,31 +10,89 @@ module RestApiGenerator
8
10
  source_root File.expand_path("templates", __dir__)
9
11
 
10
12
  argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
13
+ class_option :eject, type: :boolean, default: false
11
14
  class_option :scope, type: :string, default: ""
15
+ class_option :father, type: :string, default: ""
12
16
 
13
17
  API_CONTROLLER_DIR_PATH = "app/controllers"
14
18
  API_TEST_DIR_PATH = "spec/requests"
15
19
 
16
20
  def create_service_file
17
- Rails::Generators.invoke("model", [file_name, build_model_attributes])
18
- if options["scope"].empty?
19
- controller_path = "#{API_CONTROLLER_DIR_PATH}/#{file_name.pluralize}_controller.rb"
20
- controller_test_path = "#{API_TEST_DIR_PATH}/#{file_name.pluralize}_controller_spec.rb"
21
- template "rest_api_controller.rb", controller_path
22
- template "rest_api_spec.rb", controller_test_path
23
- routes_string = "resources :#{file_name.pluralize}"
24
- route routes_string
21
+ create_model_files
22
+
23
+ # Create controller and specs
24
+ controller_path = "#{API_CONTROLLER_DIR_PATH}#{scope_path}/#{file_name.pluralize}_controller.rb"
25
+ controller_test_path = "#{API_TEST_DIR_PATH}#{scope_path}/#{file_name.pluralize}_controller_spec.rb"
26
+
27
+ template controller_template, controller_path
28
+ template spec_controller_template, controller_test_path
29
+
30
+ if options["scope"].blank? && options["father"].blank?
31
+ route "resources :#{file_name.pluralize}"
25
32
  else
26
- scope_path = options["scope"].pluralize
27
- controller_path = "#{API_CONTROLLER_DIR_PATH}/#{scope_path}/#{file_name.pluralize}_controller.rb"
28
- controller_test_path = "#{API_TEST_DIR_PATH}/#{scope_path}/#{file_name.pluralize}_controller_spec.rb"
29
- template "child_api_controller.rb", controller_path
30
- template "child_api_spec.rb", controller_test_path
33
+ log("You need to manually setup routes files for nested or scoped resource")
31
34
  end
32
35
  end
33
36
 
34
37
  private
35
38
 
39
+ def scope_path
40
+ return "" if options["scope"].blank? && options["father"].blank?
41
+
42
+ if options["scope"].present? && options["father"].present?
43
+ "/" + option_to_path(options["scope"]) + "/" + option_to_path(options["father"])
44
+ else
45
+ "/" + option_to_path(options["scope"]) + option_to_path(options["father"])
46
+ end
47
+ end
48
+
49
+ def scope_namespacing(&block)
50
+ content = capture(&block)
51
+ content = wrap_with_scope(content) if options["scope"].present? || options["father"].present?
52
+ concat(content)
53
+ end
54
+
55
+ def module_namespace
56
+ if options["scope"].present? && options["father"].present?
57
+ options["scope"] + "::" + options["father"]
58
+ else
59
+ options["scope"] + options["father"]
60
+ end
61
+ end
62
+
63
+ def wrap_with_scope(content)
64
+ content = indent(content).chomp
65
+ "module #{module_namespace}\n#{content}\nend\n"
66
+ end
67
+
68
+ def controller_template
69
+ if options["eject"]
70
+ if options["father"].present?
71
+ "child_api_controller.rb"
72
+ else
73
+ "rest_api_controller.rb"
74
+ end
75
+ elsif options["father"].present?
76
+ "implicit_child_resource_controller.rb"
77
+ else
78
+ "implicit_resource_controller.rb"
79
+ end
80
+ end
81
+
82
+ def spec_controller_template
83
+ if options["father"].present?
84
+ "child_api_spec.rb"
85
+ else
86
+ "rest_api_spec.rb"
87
+ end
88
+ end
89
+
90
+ def create_model_files
91
+ g = Rails::Generators::ModelGenerator.new([file_name, build_model_attributes])
92
+ g.destination_root = destination_root
93
+ g.invoke_all
94
+ end
95
+
36
96
  def build_model_attributes
37
97
  model_attributes = []
38
98
  attributes.each do |attribute|
@@ -1,9 +1,10 @@
1
+ <% scope_namespacing do -%>
1
2
  class <%= class_name.pluralize %>Controller < ApplicationController
2
- before_action :set_<%= options['scope'].downcase %>
3
- before_action :set_<%= singular_name %>, only: %i[show update destroy]
3
+ before_action :set_<%= options['father'].downcase.singularize %>
4
+ before_action :set_<%= singular_name %>, only: %i[ show update destroy ]
4
5
 
5
6
  def index
6
- @<%= plural_name %> = @<%= options['scope'].downcase %>.<%= plural_name %>
7
+ @<%= plural_name %> = @<%= options['father'].downcase.singularize %>.<%= plural_name %>
7
8
  render json: @<%= plural_name %>, status: :ok
8
9
  end
9
10
 
@@ -12,7 +13,7 @@ class <%= class_name.pluralize %>Controller < ApplicationController
12
13
  end
13
14
 
14
15
  def create
15
- @<%= singular_name %> = @<%= options['scope'].downcase %>.<%= plural_name %>.create!(<%= singular_name %>_params)
16
+ @<%= singular_name %> = @<%= options['father'].downcase.singularize %>.<%= plural_name %>.create!(<%= singular_name %>_params)
16
17
  render json: @<%= singular_name %>, status: :created
17
18
  end
18
19
 
@@ -25,18 +26,18 @@ class <%= class_name.pluralize %>Controller < ApplicationController
25
26
  @<%= singular_name %>.destroy!
26
27
  end
27
28
 
28
-
29
29
  private
30
30
 
31
- def set_<%= options['scope'].downcase %>
32
- @<%= options['scope'].downcase %> = <%= options['scope'] %>.find(params[:<%= options['scope'].downcase %>_id])
31
+ def set_<%= options['father'].downcase.singularize %>
32
+ @<%= options['father'].downcase %> = <%= options['father'] %>.find(params[:<%= options['father'].downcase.singularize %>_id])
33
33
  end
34
34
 
35
35
  def set_<%= singular_name %>
36
- @<%= singular_name %> = @<%= options['scope'].downcase %>.<%= plural_name %>.find(params[:id])
36
+ @<%= singular_name %> = @<%= options['father'].downcase.singularize %>.<%= plural_name %>.find(params[:id])
37
37
  end
38
38
 
39
39
  def <%= singular_name %>_params
40
40
  params.require(:<%= singular_name %>).permit(<%= attributes.map { |a| ':' + a.name }.join(', ') %>)
41
41
  end
42
- end
42
+ end
43
+ <% end -%>
@@ -1,14 +1,36 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
- RSpec.describe "<%=class_name %>", type: :request do
3
+ RSpec.describe "<%= class_name %>", type: :request do
4
4
  let(:valid_attributes) { attributes_for(:<%= singular_table_name %>) }
5
5
 
6
- describe "POST /<%= plural_name%>" do
6
+ describe "GET /<%= plural_name %>" do
7
+ let(:<%= options['father'].downcase.singularize %>) { create(:<%= options['father'].downcase.singularize %>) }
8
+ let(:<%= singular_table_name %>) { create(:<%=singular_table_name %>, <%= options['father'].downcase %>: <%= options['father'].downcase %>) }
9
+
10
+ it "renders a successful response" do
11
+ get "<%= spec_routes[:index] %>"
12
+ expect(response).to be_successful
13
+ end
14
+ end
15
+
16
+
17
+ describe "GET /<%= singular_name %>" do
18
+ let(:<%= options['father'].downcase.singularize %>) { create(:<%= options['father'].downcase.singularize %>) }
19
+ let(:<%= singular_table_name %>) { create(:<%=singular_table_name %>, <%= options['father'].downcase.singularize %>: <%= options['father'].downcase %>)}
20
+
21
+ it "gets an <%= singular_name %>" do
22
+ get "<%= spec_routes[:show] %>"
23
+ expect(response).to be_successful
24
+ end
25
+ end
26
+
27
+
28
+ describe "POST /<%= plural_name %>" do
7
29
  context "with valid parameters" do
8
- it "creates a new <%=singular_name %>" do
9
- <%= options['scope'].downcase %> = create(:<%= options['scope'].downcase %>)
30
+ let(:<%= options['father'].downcase.singularize %>) { create(:<%= options['father'].downcase.singularize %>) }
31
+ it "creates a new <%= singular_name %>" do
10
32
  expect do
11
- post "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%= plural_name %>",
33
+ post "<%= spec_routes[:create] %>",
12
34
  params: { <%= singular_name %>: valid_attributes }
13
35
  end.to change(<%= class_name %>, :count).by(1)
14
36
  end
@@ -16,44 +38,25 @@ RSpec.describe "<%=class_name %>", type: :request do
16
38
  end
17
39
 
18
40
  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 %>)}
41
+ let(:<%= options['father'].downcase.singularize %>) { create(:<%= options['father'].downcase.singularize %>) }
42
+ let(:<%= singular_table_name %>) { create(:<%=singular_table_name %>, <%= options['father'].downcase.singularize %>: <%= options['father'].downcase.singularize %>)}
21
43
 
22
- it "updates an <%=singular_name %>" do
23
- patch "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%=plural_name %>/#{<%= singular_name %>.id}",
44
+ it "updates an <%= singular_name %>" do
45
+ patch "<%= spec_routes[:update] %>",
24
46
  params: { <%= singular_name %>: valid_attributes }
25
47
  expect(response).to have_http_status(:success)
26
48
  end
27
49
  end
28
50
 
29
51
  describe "DELETE /<%= singular_name %>" do
30
- let(:<%= options['scope'].downcase %>) {create(:<%= options['scope'].downcase %>)}
52
+ let(:<%= options['father'].downcase.singularize %>) { create(:<%= options['father'].downcase.singularize %>) }
31
53
 
32
- it "deletes an <%=singular_name %>" do
33
- <%= singular_table_name %> = create(:<%=singular_table_name %>, <%= options['scope'].downcase %>: <%= options['scope'].downcase %>)
54
+ it "deletes an <%= singular_name %>" do
55
+ <%= singular_table_name %> = create(:<%=singular_table_name %>, <%= options['father'].downcase.singularize %>: <%= options['father'].downcase.singularize %>)
34
56
  expect do
35
- delete "/<%= options['scope'].downcase.pluralize %>/#{<%= options['scope'].downcase %>.id}/<%=plural_name %>/#{<%= singular_name %>.id}"
57
+ delete "<%= spec_routes[:delete] %>"
36
58
  end.to change(<%= class_name %>, :count).by(-1)
37
59
  end
38
60
  end
39
61
 
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
62
+ end
@@ -0,0 +1,4 @@
1
+ <% scope_namespacing do -%>
2
+ class <%= class_name.pluralize %>Controller < RestApiGenerator::ChildResourceController
3
+ end
4
+ <% end -%>
@@ -0,0 +1,4 @@
1
+ <% scope_namespacing do -%>
2
+ class <%= class_name.pluralize %>Controller < RestApiGenerator::ResourceController
3
+ end
4
+ <% end -%>
@@ -1,3 +1,4 @@
1
+ <% scope_namespacing do -%>
1
2
  class <%= class_name.pluralize %>Controller < ApplicationController
2
3
  before_action :set_<%= singular_name %>, only: %i[show update destroy]
3
4
 
@@ -34,3 +35,4 @@ class <%= class_name.pluralize %>Controller < ApplicationController
34
35
  params.require(:<%= singular_name %>).permit(<%= attributes.map { |a| ':' + a.name }.join(', ') %>)
35
36
  end
36
37
  end
38
+ <% end -%>
@@ -7,14 +7,14 @@ RSpec.describe "<%= class_name %>", type: :request do
7
7
  describe "GET /<%= plural_name %>" do
8
8
  it "returns http success" do
9
9
  create(:<%= singular_table_name %>)
10
- get "/<%= plural_name %>"
10
+ get "<%= spec_routes[:index] %>"
11
11
  expect(response).to have_http_status(:success)
12
12
  end
13
13
  end
14
14
 
15
15
  describe "GET /<%= plural_name %>/:id" do
16
16
  it "returns http success" do
17
- get "/<%= plural_name %>/#{<%= singular_name %>.id}"
17
+ get "<%= spec_routes[:show] %>"
18
18
  expect(response).to have_http_status(:success)
19
19
  end
20
20
  end
@@ -22,7 +22,7 @@ RSpec.describe "<%= class_name %>", type: :request do
22
22
  describe "POST /<%= plural_name %>" do
23
23
  it "creates a new item" do
24
24
  expect do
25
- post "/<%= plural_name %>",
25
+ post "<%= spec_routes[:create] %>",
26
26
  params: { <%= singular_name %>: valid_attributes }
27
27
  end.to change(<%= class_name %>, :count).by(1)
28
28
  end
@@ -30,7 +30,7 @@ RSpec.describe "<%= class_name %>", type: :request do
30
30
 
31
31
  describe "PATCH /<%= plural_name %>/:id" do
32
32
  it "return http success" do
33
- patch "/<%= plural_name %>/#{<%= singular_name %>.id}",
33
+ patch "<%= spec_routes[:update] %>",
34
34
  params: { <%= singular_name %>: valid_attributes }
35
35
  expect(response).to have_http_status(:success)
36
36
  end
@@ -40,7 +40,7 @@ RSpec.describe "<%= class_name %>", type: :request do
40
40
  it "deletes an <%= plural_name %>" do
41
41
  item = create(:<%= singular_name %>)
42
42
  expect do
43
- delete "/<%= plural_name %>/#{item.id}"
43
+ delete "<%= spec_routes[:delete] %>"
44
44
  end.to change(<%= class_name %>, :count).by(-1)
45
45
  end
46
46
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.dirname(__FILE__) + "/rest_api_generator"
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_controller"
4
+
5
+ module RestApiGenerator
6
+ class ApplicationController < ActionController::Base
7
+ end
8
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RestApiGenerator
4
+ class ChildResourceController < RestApiGenerator.parent_controller.constantize
5
+ include Orderable
6
+
7
+ before_action :set_parent_resource
8
+ before_action :set_resource, only: [:show, :update, :destroy]
9
+
10
+ def index
11
+ @resources = resources
12
+ @resources = @resources.filter_resource(params_for_filter) if resource_class.include?(Filterable)
13
+ @resources = @resources.order(ordering_params(params[:sort])) if params[:sort]
14
+ render json: @resources, status: :ok
15
+ end
16
+
17
+ def show
18
+ render json: @resource, status: :ok
19
+ end
20
+
21
+ def create
22
+ @resource = resources.create!(resource_created_params)
23
+ render json: @resource, status: :created
24
+ end
25
+
26
+ def update
27
+ @resource.update!(resource_updated_params)
28
+ render json: @resource, status: :ok
29
+ end
30
+
31
+ def destroy
32
+ @resource.destroy!
33
+ end
34
+
35
+ private
36
+
37
+ def resources
38
+ @parent_resource.send(resource_class.to_s.downcase.pluralize)
39
+ end
40
+
41
+ def parent_resource_class
42
+ parent_resource_by_controller_name
43
+ end
44
+
45
+ def resource_class
46
+ resource_by_controller_name
47
+ end
48
+
49
+ # Params
50
+ def resource_created_params
51
+ resource_params
52
+ end
53
+
54
+ def resource_updated_params
55
+ resource_params
56
+ end
57
+
58
+ def resource_params
59
+ params.require(resource_class.model_name.singular.to_sym).permit(resource_attributes)
60
+ end
61
+
62
+ def resource_attributes
63
+ resource_class.attribute_names.map(&:to_sym)
64
+ end
65
+
66
+ def params_for_filter
67
+ params.slice(*resource_class.filter_scopes)
68
+ end
69
+
70
+ # Before actions
71
+ def set_parent_resource
72
+ @parent_resource = parent_resource_class.find(parent_record_id)
73
+ end
74
+
75
+ def set_resource
76
+ @resource = resources.find(record_id)
77
+ end
78
+
79
+ # UsersController => User
80
+ def resource_by_controller_name(controller_name = self.class.to_s)
81
+ controller_name.split(Regexp.union(["Controller", "::"]))[-1].singularize.constantize
82
+ end
83
+
84
+ # Users::DevicesController => User
85
+ def parent_resource_by_controller_name(controller_name = self.class.to_s)
86
+ controller_name.split(Regexp.union(["Controller", "::"]))[-2].singularize.constantize
87
+ end
88
+
89
+ def parent_record_id
90
+ params.dig("#{parent_resource_class.to_s.downcase.singularize}_id")
91
+ end
92
+
93
+ def record_id
94
+ params.permit(:id)[:id]
95
+ end
96
+ end
97
+ end
@@ -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.2"
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,7 @@
1
1
  # frozen_string_literal: true
2
+ $:.push File.expand_path("../lib", __FILE__)
2
3
 
3
4
  require_relative "lib/rest_api_generator/version"
4
- require_relative "lib/rest_api_generator"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "rest-api-generator"
@@ -27,9 +27,15 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- spec.add_runtime_dependency("railties", ">= 5.0.0")
31
-
32
30
  # For more information and examples about making a new gem, check out our
33
31
  # guide at: https://bundler.io/guides/creating_gem.html
34
32
  spec.metadata["rubygems_mfa_required"] = "true"
33
+
34
+ spec.add_dependency "rails", ">= 5.0"
35
+
36
+ spec.add_development_dependency 'ammeter', '~> 1.1.5'
37
+ spec.add_development_dependency 'rspec-rails', '~> 6.0.0'
38
+ spec.add_development_dependency 'sqlite3'
39
+ spec.add_development_dependency 'database_cleaner'
40
+
35
41
  end
metadata CHANGED
@@ -1,29 +1,85 @@
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.2
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: 2022-12-29 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: rspec-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 6.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 6.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: database_cleaner
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'
27
83
  description: This gem helps you to build a Ruby on Rails REST API faster, using a
28
84
  scaffold-like generator that follows the best practices.
29
85
  email:
@@ -43,12 +99,20 @@ files:
43
99
  - lib/generators/rest_api_generator/resource_generator.rb
44
100
  - lib/generators/rest_api_generator/templates/child_api_controller.rb.tt
45
101
  - lib/generators/rest_api_generator/templates/child_api_spec.rb.tt
102
+ - lib/generators/rest_api_generator/templates/implicit_child_resource_controller.rb.tt
103
+ - lib/generators/rest_api_generator/templates/implicit_resource_controller.rb.tt
46
104
  - lib/generators/rest_api_generator/templates/rest_api_controller.rb.tt
47
105
  - lib/generators/rest_api_generator/templates/rest_api_spec.rb.tt
106
+ - lib/rest-api-generator.rb
48
107
  - lib/rest_api_generator.rb
108
+ - lib/rest_api_generator/application_controller.rb
109
+ - lib/rest_api_generator/child_resource_controller.rb
49
110
  - lib/rest_api_generator/custom_error.rb
50
111
  - lib/rest_api_generator/error_handler.rb
112
+ - lib/rest_api_generator/filterable.rb
51
113
  - lib/rest_api_generator/helpers/render.rb
114
+ - lib/rest_api_generator/orderable.rb
115
+ - lib/rest_api_generator/resource_controller.rb
52
116
  - lib/rest_api_generator/version.rb
53
117
  - rest-api-generator.gemspec
54
118
  - sig/rest_api_generator.rbs
@@ -76,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
140
  - !ruby/object:Gem::Version
77
141
  version: '0'
78
142
  requirements: []
79
- rubygems_version: 3.3.3
143
+ rubygems_version: 3.3.7
80
144
  signing_key:
81
145
  specification_version: 4
82
146
  summary: Build a Ruby on Rails REST API faster