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.
Files changed (28) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +149 -0
  3. data/bin/rails_on_rails +5 -0
  4. data/lib/autogenerators/bash_commands/generate_controller.sh +1 -0
  5. data/lib/autogenerators/bash_commands/generate_model.sh +1 -0
  6. data/lib/autogenerators/bash_commands/install_rspec.sh +1 -0
  7. data/lib/autogenerators/generator_templates/application_record.txt +8 -0
  8. data/lib/autogenerators/generator_templates/controller.txt +14 -0
  9. data/lib/autogenerators/generator_templates/test_rspec_controller.txt +169 -0
  10. data/lib/autogenerators/generator_templates/test_seeder.txt +45 -0
  11. data/lib/autogenerators/handlers/controller.rb +28 -0
  12. data/lib/autogenerators/handlers/initialize_api_docs.rb +24 -0
  13. data/lib/autogenerators/handlers/initialize_global_controller.rb +7 -0
  14. data/lib/autogenerators/handlers/initialize_rspec.rb +23 -0
  15. data/lib/autogenerators/handlers/test_rspec_controller.rb +16 -0
  16. data/lib/autogenerators/handlers/test_seeder.rb +16 -0
  17. data/lib/autogenerators/rails_templates/api_documentation.rake +181 -0
  18. data/lib/autogenerators/rails_templates/auth_helper.rb +73 -0
  19. data/lib/autogenerators/rails_templates/documentation/index.html.erb +121 -0
  20. data/lib/autogenerators/rails_templates/documentation/layout.html.erb +14 -0
  21. data/lib/autogenerators/rails_templates/documentation_controller.rb +139 -0
  22. data/lib/autogenerators/rails_templates/global_controller.rb +411 -0
  23. data/lib/autogenerators/rails_templates/seeds.rb +91 -0
  24. data/lib/constants/cli_constants.rb +56 -0
  25. data/lib/constants/options.rb +61 -0
  26. data/lib/rails_on_rails.rb +124 -0
  27. data/lib/utils/rails_methods.rb +9 -0
  28. 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
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'rails_on_rails'
5
+ Commander.actions(ARGV)
@@ -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,8 @@
1
+ def upsert find, create
2
+ existing = self.find_by(find)
3
+ if existing
4
+ self.where(find).update(create).first
5
+ else
6
+ self.create(create)
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ class {{ MODEL }}Controller < GlobalController
2
+
3
+ def model
4
+ { model: {{ MODEL }} }
5
+ end
6
+
7
+ def default_options
8
+ {}
9
+ end
10
+
11
+ def render_params
12
+ handle_params({{ PARAMS }})
13
+ end
14
+ end
@@ -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)