rest-api-generator 0.1.1 → 0.1.2

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