rails_on_rails 0.0.9
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 +7 -0
- data/README.md +149 -0
- data/bin/rails_on_rails +5 -0
- data/lib/autogenerators/bash_commands/generate_controller.sh +1 -0
- data/lib/autogenerators/bash_commands/generate_model.sh +1 -0
- data/lib/autogenerators/bash_commands/install_rspec.sh +1 -0
- data/lib/autogenerators/generator_templates/application_record.txt +8 -0
- data/lib/autogenerators/generator_templates/controller.txt +14 -0
- data/lib/autogenerators/generator_templates/test_rspec_controller.txt +169 -0
- data/lib/autogenerators/generator_templates/test_seeder.txt +45 -0
- data/lib/autogenerators/handlers/controller.rb +28 -0
- data/lib/autogenerators/handlers/initialize_api_docs.rb +24 -0
- data/lib/autogenerators/handlers/initialize_global_controller.rb +7 -0
- data/lib/autogenerators/handlers/initialize_rspec.rb +23 -0
- data/lib/autogenerators/handlers/test_rspec_controller.rb +16 -0
- data/lib/autogenerators/handlers/test_seeder.rb +16 -0
- data/lib/autogenerators/rails_templates/api_documentation.rake +181 -0
- data/lib/autogenerators/rails_templates/auth_helper.rb +73 -0
- data/lib/autogenerators/rails_templates/documentation/index.html.erb +121 -0
- data/lib/autogenerators/rails_templates/documentation/layout.html.erb +14 -0
- data/lib/autogenerators/rails_templates/documentation_controller.rb +139 -0
- data/lib/autogenerators/rails_templates/global_controller.rb +411 -0
- data/lib/autogenerators/rails_templates/seeds.rb +91 -0
- data/lib/constants/cli_constants.rb +56 -0
- data/lib/constants/options.rb +61 -0
- data/lib/rails_on_rails.rb +124 -0
- data/lib/utils/rails_methods.rb +9 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 36958c631c1d24258e9702004ed3508e01cbb96fc73e0a8fc438f144e9e61c3c
|
4
|
+
data.tar.gz: d06ab2bf6e5dcc635cd1b5a9c877456a327cac3d559a2a4e15b7a6c5a9105982
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 297087d5e99077cdb55c44498b2e71dded0ceab7fc6d4e50a0de308d08ba9407fc300c85885dd9c8002f08abaa1e58df3f3bb4c04ac9e1d749624a8f713e9659
|
7
|
+
data.tar.gz: a0de593f1c62b04e9f91a7d076f5dd22ca74188ba6407bcc34ef056ef979e376cca6554202845e0b85a8e6540e28de2161e5a86ea5cc97294e5d2d57907ce918
|
data/README.md
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# Rails on Rails
|
2
|
+
|
3
|
+
All commands must be execute in your Rails root project directory
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
Install in your gem file and a global install for this gem
|
7
|
+
|
8
|
+
Global Install:
|
9
|
+
`gem install rails_on_rails`
|
10
|
+
|
11
|
+
Gemfile Install:
|
12
|
+
`gem 'rails_on_rails'`
|
13
|
+
|
14
|
+
## Gem Dependencies
|
15
|
+
- Rails Version 5: `gem 'rails', '~> 5'`
|
16
|
+
- Rails Rspec Version >= 3.8: `gem 'rspec-rails', '~> 3.8'`
|
17
|
+
- Faker Version >= 1.9: `gem 'faker', '~> 1.9'`
|
18
|
+
|
19
|
+
## Initialize your project with Rails + 1
|
20
|
+
If you run into hangups with spring, run `spring stop` before your `rails_on_rails`
|
21
|
+
Then `spring server` to resume spring
|
22
|
+
|
23
|
+
```
|
24
|
+
rails_on_rails init
|
25
|
+
```
|
26
|
+
|
27
|
+
Before running the server add this initializer for the API Documentation
|
28
|
+
in your `config/application.rb` add this inside of your Rails::Apllication inherited class
|
29
|
+
```
|
30
|
+
config.after_initialize do
|
31
|
+
require 'rake'
|
32
|
+
Rails.application.reload_routes!
|
33
|
+
Rails.application.load_tasks
|
34
|
+
Rake::Task["api_documentation:frontend_javascript"].invoke
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
In your `config/routes.rb` add this route for your documentation page
|
39
|
+
```
|
40
|
+
resources :documentation, only: :index
|
41
|
+
```
|
42
|
+
|
43
|
+
## Generate your CRUD Operations for Index, Show, Create, Update, & Destroy
|
44
|
+
```
|
45
|
+
rails_on_rails model <ModelName> <*rails-model-generate-parameters>
|
46
|
+
```
|
47
|
+
|
48
|
+
By default all our basic CRUD operations are complete for: Index, Show, Create, Update, & Destroy
|
49
|
+
There are other functions you can use as well
|
50
|
+
|
51
|
+
With your default CRUD operations you have many tools at your deposible
|
52
|
+
|
53
|
+
For all of your options, you can see all the available options in the API docs based on our schema in for that model
|
54
|
+
|
55
|
+
### Querystring paramters
|
56
|
+
- Index:
|
57
|
+
-- include: Include will grab any associated tables with that endpoint separated by a comma (Check the docs for your schema's options)
|
58
|
+
-- where: Where will be a custom where hash the string string format is a json object without curly brackets (Check the docs for your schema's options)
|
59
|
+
-- like: Like will be a custom where string with a like operator all on all values given the string string format is a json object without curly brackets (Check the docs for your schema's options)
|
60
|
+
-- order: Order will be a string passed into order the options are all separated by a comma in querystring (Check the docs for your schema's options)
|
61
|
+
|
62
|
+
- Show:
|
63
|
+
-- include: Include will grab any associated tables with that endpoint separated by a comma (Check the docs for your schema's options)
|
64
|
+
-- where: Where will be a custom where hash the string string format is a json object without curly brackets (Check the docs for your schema's options)
|
65
|
+
|
66
|
+
### Body paramters
|
67
|
+
All values except id, created_at, updated_at, or deleted_at are available by default you have the available to overwrite everything
|
68
|
+
We use a custom method instead of params.permits
|
69
|
+
For associated keys like 'user_id' provide an array with the first value being a symbol for the assocation ':user'
|
70
|
+
The second value in the ActiveRecord you would like to use
|
71
|
+
When using polymorphoric assocations, it is recommended to use a hash map of types and
|
72
|
+
the value being the ActiveReord you provide in your schema with the search key being the string_type in the database
|
73
|
+
|
74
|
+
### Bonus Methods
|
75
|
+
- bulk_create: Create multiple rows the paramter is 'bulk' which is an array of create hashes
|
76
|
+
```
|
77
|
+
params[:bulk] = [{ first_name: 'Mr. Robot' },{ first_name: 'Elloit }]
|
78
|
+
```
|
79
|
+
- bulk_update: Update multiple rows the paramter is 'bulk' which is a hash of ids with the update hash
|
80
|
+
```
|
81
|
+
params[:bulk] = { 1 => { name: 'Luke Skywalker' }, 2 => { name: 'Darth Vader' } }
|
82
|
+
```
|
83
|
+
- bulk_destroy: Destroy multiple rows the paramter is 'ids' which is an array of ids
|
84
|
+
- duplicate: Create a deep clone of any row in the database with all of it's assocations included the param is 'id' the table is for the controller associated to it
|
85
|
+
- bulk_csv_create: Create multiple rows the paramter is 'file' which is a csv file separated by commas and the first line is keys and the rest of values all separated by commas
|
86
|
+
|
87
|
+
#### Declaring bonus methods in `config/routes.rb`
|
88
|
+
```
|
89
|
+
rsources :user, except: [:edit, :new] do
|
90
|
+
collection do
|
91
|
+
post 'duplicate'
|
92
|
+
post 'bulk_create'
|
93
|
+
post 'bulk_csv_create'
|
94
|
+
put 'bulk_update'
|
95
|
+
delete 'bulk_destroy'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
## API Documentation
|
101
|
+
The API Documentation requires CORS on your server, please set that up for all options for the web.
|
102
|
+
Also setup your file uploads (multipart) to be independent of erb templating
|
103
|
+
|
104
|
+
For custom headers that you may add in the future update the `lib/api_documentation.rake`
|
105
|
+
Line 48: is where you can update the needed headers for your axios ajax requests.
|
106
|
+
```
|
107
|
+
var csrfHeader = { headers: { 'X-CSRF-Token': null, 'Accept': 'application/json', 'Content-Type': 'application/json' } };
|
108
|
+
```
|
109
|
+
|
110
|
+
By default only json formats are unaccept for RESTful API JSON formatting
|
111
|
+
|
112
|
+
### Querystring parameters
|
113
|
+
A querystring in the url looks like this
|
114
|
+
`<protocol>://<host-name>/<path-name></path-name>?<querystring-key>=<querystring-value>&<querystring-key>=<querystring-value>`
|
115
|
+
|
116
|
+
Anything after and including the question mark is a querystring
|
117
|
+
You chain multiple querystring options spaced with '&'
|
118
|
+
|
119
|
+
The API Docs do the string maniplication for you under the hood.
|
120
|
+
|
121
|
+
The options for our API are:
|
122
|
+
/* key = value */
|
123
|
+
- include = <include-options-separated-by-a-comma>
|
124
|
+
- where = <where-options-separated-by-a-comma>
|
125
|
+
- like = <like-options-separated-by-a-comma>
|
126
|
+
- order = <order-options-separated-by-a-comma>
|
127
|
+
|
128
|
+
Those options are given in the description for the endpoint you are testing
|
129
|
+
|
130
|
+
- Include will grab any associated tables with that endpoint
|
131
|
+
- Where will grab data where the options are true
|
132
|
+
- Like will grab data where the options are true but can be partially correct for searching
|
133
|
+
- Order will grab the data in the order you request
|
134
|
+
|
135
|
+
### Body parameters
|
136
|
+
Body parameters are the key and value pairs you send in a request
|
137
|
+
Those options are available as well
|
138
|
+
Keeping the same key-value pair input UI with different functionality
|
139
|
+
Under the 'Body' title
|
140
|
+
|
141
|
+
### Path parameters
|
142
|
+
Path parameters are the key and value pairs you send in a request through the url
|
143
|
+
Keeping the same key-value pair input UI however other the value will be in the url
|
144
|
+
Under the 'Param' title
|
145
|
+
|
146
|
+
### Body Data Type option
|
147
|
+
This dropdown is only used for file uploads by default they are set to JSON
|
148
|
+
Use 'Form Data' for file uploads
|
149
|
+
|
data/bin/rails_on_rails
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rails generate controller $@
|
@@ -0,0 +1 @@
|
|
1
|
+
rails generate model $@
|
@@ -0,0 +1 @@
|
|
1
|
+
rails generate rspec:install
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
|
4
|
+
route_name = "{{ API_ROUTE }}"
|
5
|
+
config_routes = {
|
6
|
+
index: true,
|
7
|
+
show: true,
|
8
|
+
create: true,
|
9
|
+
update: true,
|
10
|
+
destroy: true,
|
11
|
+
}
|
12
|
+
|
13
|
+
RSpec.configure {|c| c.before { expect(controller).not_to be_nil }}
|
14
|
+
RSpec.describe {{ MODEL }}Controller, type: :request do
|
15
|
+
|
16
|
+
created = nil
|
17
|
+
created_2 = nil
|
18
|
+
|
19
|
+
blacklist = {}
|
20
|
+
associations = get_associations({{ MODEL }}).reject { |e| blacklist[e.to_sym] }
|
21
|
+
|
22
|
+
includes = include_querystrings(associations)
|
23
|
+
wheres = where_querystrings([
|
24
|
+
{ id: 1 },
|
25
|
+
])
|
26
|
+
likes = like_querystrings([
|
27
|
+
{ id: 1 },
|
28
|
+
])
|
29
|
+
order = order_querystrings([
|
30
|
+
'id',
|
31
|
+
'created_at',
|
32
|
+
'updated_at',
|
33
|
+
])
|
34
|
+
|
35
|
+
pagination_querystrings = concat_all_with_default([
|
36
|
+
includes,
|
37
|
+
wheres,
|
38
|
+
likes,
|
39
|
+
order,
|
40
|
+
])
|
41
|
+
|
42
|
+
show_querystrings = concat_all_with_default([
|
43
|
+
includes,
|
44
|
+
])
|
45
|
+
|
46
|
+
if config_routes[:index]
|
47
|
+
pagination_querystrings.each do |val|
|
48
|
+
it "No Auth: Index: No 500 errors" do
|
49
|
+
get "#{route_name}?#{val}"
|
50
|
+
expect(response.status).to be < 500
|
51
|
+
end
|
52
|
+
|
53
|
+
it "Index: No 500 errors" do
|
54
|
+
get "#{route_name}?#{val}", headers: @headers
|
55
|
+
expect(response.status).to be < 500
|
56
|
+
end
|
57
|
+
|
58
|
+
it "Index: Body Format" do
|
59
|
+
get "#{route_name}?#{val}", headers: @headers
|
60
|
+
@resp = JSON.parse(response.body)
|
61
|
+
@check = @resp.is_a?(Hash) && @resp["data"].is_a?(Array) && @resp["count"] >= @resp["data"].length
|
62
|
+
expect(@check).to be true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if config_routes[:show]
|
68
|
+
show_querystrings.each do |val|
|
69
|
+
it "No Auth: Show: No 500 errors" do
|
70
|
+
get "#{route_name}/1?#{val}"
|
71
|
+
expect(response.status).to be < 500
|
72
|
+
end
|
73
|
+
|
74
|
+
it "Show: No 500 errors" do
|
75
|
+
get "#{route_name}/1?#{val}", headers: @headers
|
76
|
+
expect(response.status).to be < 500
|
77
|
+
end
|
78
|
+
|
79
|
+
it "Show: Body Format" do
|
80
|
+
get "#{route_name}/1?#{val}", headers: @headers
|
81
|
+
@resp = JSON.parse(response.body)
|
82
|
+
@check = @resp.is_a?(Hash)
|
83
|
+
expect(@check).to be true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
if config_routes[:create]
|
89
|
+
it "No Auth: Create: No 500 errors" do
|
90
|
+
post "#{route_name}", params: {}
|
91
|
+
expect(response.status).to be < 500
|
92
|
+
end
|
93
|
+
|
94
|
+
it "Create: No 500 errors" do
|
95
|
+
post "#{route_name}", params: {}, headers: @headers
|
96
|
+
created = JSON.parse(response.body)
|
97
|
+
expect(response.status).to be < 500
|
98
|
+
end
|
99
|
+
|
100
|
+
it "Create: Body Format" do
|
101
|
+
post "#{route_name}", params: {}, headers: @headers
|
102
|
+
@resp = JSON.parse(response.body)
|
103
|
+
created_2 = @resp
|
104
|
+
@check = @resp.is_a?(Hash)
|
105
|
+
expect(@check).to be true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
if config_routes[:update]
|
110
|
+
it "No Auth: Update: No 500 errors" do
|
111
|
+
patch "#{route_name}/1", params: {}
|
112
|
+
expect(response.status).to be < 500
|
113
|
+
end
|
114
|
+
|
115
|
+
it "Update: No 500 errors" do
|
116
|
+
patch "#{route_name}/1", params: {}, headers: @headers
|
117
|
+
expect(response.status).to be < 500
|
118
|
+
end
|
119
|
+
|
120
|
+
it "Update: Body Format" do
|
121
|
+
patch "#{route_name}/1", params: {}, headers: @headers
|
122
|
+
@resp = JSON.parse(response.body)
|
123
|
+
@check = @resp.is_a?(Array)
|
124
|
+
expect(@check).to be true
|
125
|
+
end
|
126
|
+
|
127
|
+
it "No Auth: Update: No 500 errors" do
|
128
|
+
put "#{route_name}/1", params: {}
|
129
|
+
expect(response.status).to be < 500
|
130
|
+
end
|
131
|
+
|
132
|
+
it "Update: No 500 errors" do
|
133
|
+
put "#{route_name}/1", params: {}, headers: @headers
|
134
|
+
expect(response.status).to be < 500
|
135
|
+
end
|
136
|
+
|
137
|
+
it "Update: Body Format" do
|
138
|
+
put "#{route_name}/1", params: {}, headers: @headers
|
139
|
+
@resp = JSON.parse(response.body)
|
140
|
+
@check = @resp.is_a?(Array)
|
141
|
+
expect(@check).to be true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
if config_routes[:destroy]
|
146
|
+
it "No Auth: Destroy: No 500 errors" do
|
147
|
+
past = created ? created.symbolize_keys : { id: 6 }
|
148
|
+
id = past[:id]
|
149
|
+
delete "#{route_name}/#{id}"
|
150
|
+
expect(response.status).to be < 500
|
151
|
+
end
|
152
|
+
|
153
|
+
it "Destroy: No 500 errors" do
|
154
|
+
past = created ? created.symbolize_keys : { id: 6 }
|
155
|
+
id = past[:id]
|
156
|
+
delete "#{route_name}/#{id}", headers: @headers
|
157
|
+
expect(response.status).to be < 500
|
158
|
+
end
|
159
|
+
|
160
|
+
it "Destroy: Body Format" do
|
161
|
+
past = created_2 ? created_2.symbolize_keys : { id: 7 }
|
162
|
+
id = past[:id]
|
163
|
+
delete "#{route_name}/#{id}", headers: @headers
|
164
|
+
@resp = response.body
|
165
|
+
@check = @resp == ''
|
166
|
+
expect(@check).to be true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'faker'
|
2
|
+
|
3
|
+
def upsert find, create
|
4
|
+
existing = {{ MODEL }}.find_by(find)
|
5
|
+
if existing
|
6
|
+
{{ MODEL }}.where(find).update(create).first
|
7
|
+
else
|
8
|
+
{{ MODEL }}.create(create)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
time = 5
|
13
|
+
|
14
|
+
black_list = {
|
15
|
+
id: true,
|
16
|
+
created_at: true,
|
17
|
+
updated_at: true,
|
18
|
+
}
|
19
|
+
|
20
|
+
columns = {{ MODEL }}.columns_hash.map do |key, val|
|
21
|
+
{ key: key.to_sym, data_type: val.type }
|
22
|
+
end.select { |e| !black_list[e[:key]] }
|
23
|
+
|
24
|
+
array = []
|
25
|
+
time.times do
|
26
|
+
obj = columns.each_with_object({}) do |e, acc|
|
27
|
+
key = e[:key]
|
28
|
+
if e[:data_type] == :string
|
29
|
+
acc[key] = Faker::Lorem.sentence.to_s
|
30
|
+
elsif e[:data_type] == :datetime
|
31
|
+
acc[key] = DateTime.now
|
32
|
+
elsif e[:data_type] == :integer
|
33
|
+
acc[key] = 1
|
34
|
+
elsif e[:data_type] == :boolean
|
35
|
+
acc[key] = false
|
36
|
+
elsif e[:data_type] == :text
|
37
|
+
acc[key] = Faker::Lorem.paragraph.to_s
|
38
|
+
end
|
39
|
+
end
|
40
|
+
array.push(obj)
|
41
|
+
end
|
42
|
+
|
43
|
+
array.each_with_index do |e, i|
|
44
|
+
upsert({ id: i + 1 }, e)
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative '../../utils/rails_methods.rb'
|
2
|
+
|
3
|
+
MODEL_NAME = ARGV[0]
|
4
|
+
MODEL_PARAMS = ARGV
|
5
|
+
MODEL_PARAMS.shift
|
6
|
+
|
7
|
+
MODEL_SNAKE_CASE = MODEL_NAME.underscore
|
8
|
+
|
9
|
+
system("bash #{__dir__}/../bash_commands/generate_model.sh #{MODEL_NAME} #{MODEL_PARAMS.join(' ')}")
|
10
|
+
system("bash #{__dir__}/../bash_commands/generate_controller.sh #{MODEL_SNAKE_CASE} --no-assets --no-view-specs --no-helper")
|
11
|
+
|
12
|
+
controller_path = "#{Dir.pwd}/app/controllers/#{MODEL_SNAKE_CASE}_controller.rb"
|
13
|
+
template_path = "#{__dir__}/../generator_templates/controller.txt"
|
14
|
+
|
15
|
+
read_file = File.open(template_path, 'r:UTF-8', &:read)
|
16
|
+
length = MODEL_PARAMS.length
|
17
|
+
|
18
|
+
PARAMS_STRING = MODEL_PARAMS.map do |item|
|
19
|
+
str = ''
|
20
|
+
key, type = item.split(':')
|
21
|
+
str += type == 'references' ? "[:#{key}, " + "#{key.split('_').map(&:capitalize!).join('')}]" : ":#{key}"
|
22
|
+
str
|
23
|
+
end.join(', ')
|
24
|
+
|
25
|
+
read_file = read_file.gsub! '{{ MODEL }}', MODEL_NAME
|
26
|
+
read_file = read_file.gsub! '{{ PARAMS }}', PARAMS_STRING
|
27
|
+
|
28
|
+
File.write(controller_path, read_file)
|