hot-glue 0.0.7 → 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: d747beed420f47b73a42783e6ae92edd8f4508b13c471a7ae7747a1a7eddfe58
4
- data.tar.gz: 9feb6afe2493e46d7e4eef0db0c836f3d140e33c20555c5f07e7fbc896fef366
3
+ metadata.gz: 3b265c8c7f5e9fb424122d2d40eec712a7cb4f846f5daf581b75a8e4981790fa
4
+ data.tar.gz: 23e8b5857b4e8fa2391a46128a282a952355fe64c9097868b98bf8d462c9a35c
5
5
  SHA512:
6
- metadata.gz: cf3dcb49cf4a37919269ff3812d00668e2739830c6f01b1f3cc86a01abc78c3278214bb27e3c3935cf60e640460482c8b79bc1127263790e349bf82f3ea4b443
7
- data.tar.gz: 7b9576bb6ee658ffb2c05cc7a5f0c77383e70964c174e361d993c5f6f4162b94be69452fceed1fdd1988d8876b43c14c7f16b95d564136b9167604e75ee3a287
6
+ metadata.gz: 3a304db4b93d3edf92657178e0057830f224dda0e1b08c5957169d2e6f378ac6cc9137513e18001c38881d7f2594d2d608ba3de07ffa86291089c01cccecc462
7
+ data.tar.gz: 884d154c85a9688b66db56498f2f66dbda7356d06d2f5590e80c911f86e46fee5bcefc1809f6d5deb339b79fe95a95d45f823a89128105ec367f0d7b6c67a85d
data/.github/FUNDING.yml CHANGED
@@ -1,2 +1,2 @@
1
1
  github: [jasonfb]
2
- custom: ["https://jfb.teachable.com"]
2
+ custom: ["https://www.instagram.com/jfbcodes/"]
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hot-glue (0.0.7)
4
+ hot-glue (0.1.1)
5
5
  ffaker (~> 2.16)
6
6
  haml-rails (~> 2.0)
7
7
  kaminari (~> 1.2)
@@ -74,9 +74,9 @@ GEM
74
74
  bcrypt (3.1.16)
75
75
  builder (3.2.4)
76
76
  byebug (11.1.3)
77
- concurrent-ruby (1.1.8)
77
+ concurrent-ruby (1.1.9)
78
78
  crass (1.0.6)
79
- devise (4.7.3)
79
+ devise (4.8.0)
80
80
  bcrypt (~> 3.0)
81
81
  orm_adapter (~> 0.1)
82
82
  railties (>= 4.1.0)
@@ -85,7 +85,7 @@ GEM
85
85
  erubi (1.10.0)
86
86
  erubis (2.7.0)
87
87
  ffaker (2.18.0)
88
- ffi (1.14.2)
88
+ ffi (1.15.3)
89
89
  globalid (0.4.2)
90
90
  activesupport (>= 4.2.0)
91
91
  haml (5.2.1)
@@ -102,7 +102,7 @@ GEM
102
102
  haml (>= 4.0, < 6)
103
103
  nokogiri (>= 1.6.0)
104
104
  ruby_parser (~> 3.5)
105
- i18n (1.8.9)
105
+ i18n (1.8.10)
106
106
  concurrent-ruby (~> 1.0)
107
107
  kaminari (1.2.1)
108
108
  activesupport (>= 4.1.0)
@@ -116,7 +116,7 @@ GEM
116
116
  activerecord
117
117
  kaminari-core (= 1.2.1)
118
118
  kaminari-core (1.2.1)
119
- loofah (2.9.0)
119
+ loofah (2.10.0)
120
120
  crass (~> 1.0.2)
121
121
  nokogiri (>= 1.5.9)
122
122
  mail (2.7.1)
@@ -124,12 +124,14 @@ GEM
124
124
  marcel (0.3.3)
125
125
  mimemagic (~> 0.3.2)
126
126
  method_source (1.0.0)
127
- mimemagic (0.3.5)
128
- mini_mime (1.0.2)
129
- mini_portile2 (2.5.0)
127
+ mimemagic (0.3.10)
128
+ nokogiri (~> 1)
129
+ rake
130
+ mini_mime (1.1.0)
131
+ mini_portile2 (2.5.3)
130
132
  minitest (5.14.4)
131
133
  nio4r (2.5.7)
132
- nokogiri (1.11.1)
134
+ nokogiri (1.11.7)
133
135
  mini_portile2 (~> 2.5.0)
134
136
  racc (~> 1.4)
135
137
  orm_adapter (0.5.0)
@@ -167,8 +169,8 @@ GEM
167
169
  responders (3.0.1)
168
170
  actionpack (>= 5.0)
169
171
  railties (>= 5.0)
170
- ruby_parser (3.15.1)
171
- sexp_processor (~> 4.9)
172
+ ruby_parser (3.16.0)
173
+ sexp_processor (~> 4.15, >= 4.15.1)
172
174
  sass-rails (6.0.0)
173
175
  sassc-rails (~> 2.1, >= 2.1.1)
174
176
  sassc (2.4.0)
@@ -179,7 +181,7 @@ GEM
179
181
  sprockets (> 3.0)
180
182
  sprockets-rails
181
183
  tilt
182
- sexp_processor (4.15.2)
184
+ sexp_processor (4.15.3)
183
185
  sprockets (4.0.2)
184
186
  concurrent-ruby (~> 1.0)
185
187
  rack (> 1, < 3)
@@ -191,19 +193,19 @@ GEM
191
193
  temple (0.8.2)
192
194
  thor (1.1.0)
193
195
  tilt (2.0.10)
194
- turbo-rails (0.5.9)
196
+ turbo-rails (0.5.11)
195
197
  rails (>= 6.0.0)
196
198
  tzinfo (2.0.4)
197
199
  concurrent-ruby (~> 1.0)
198
200
  warden (1.2.9)
199
201
  rack (>= 2.0.9)
200
- websocket-driver (0.7.3)
202
+ websocket-driver (0.7.5)
201
203
  websocket-extensions (>= 0.1.0)
202
204
  websocket-extensions (0.1.5)
203
205
  zeitwerk (2.4.2)
204
206
 
205
207
  PLATFORMS
206
- ruby
208
+ -darwin-20
207
209
 
208
210
  DEPENDENCIES
209
211
  byebug
@@ -213,4 +215,4 @@ DEPENDENCIES
213
215
  sqlite3
214
216
 
215
217
  BUNDLED WITH
216
- 2.1.4
218
+ 2.2.19
data/README.md CHANGED
@@ -1,72 +1,118 @@
1
1
  # Hot Glue
2
2
 
3
- Hot Glue is an evolution of the best of the admin-style scaffold builders of the 2010s ([activeadmin](https://github.com/activeadmin/activeadmin), [rails_admin](https://github.com/sferik/rails_admin), and [active_scaffold](https://github.com/activescaffold/active_scaffold) being the most popular of those). It harnesses the power of Rails 6, Turbo-Rails, and Hotwire to deliver a lightning fast experience.
3
+ Hot Glue is a Rails scaffold builder for the Turbo era. It is an evolution of the admin-interface style scaffolding systems of the 2010s ([activeadmin](https://github.com/activeadmin/activeadmin), [rails_admin](https://github.com/sferik/rails_admin), and [active_scaffold](https://github.com/activescaffold/active_scaffold)).
4
4
 
5
- As well, its premise is a little different than the configuration-heavy admin interface toolkits. It will read your relationships and field types to generate your code for you, leaving you with a 'sourdough starter' to work from. If you modify the generated code, you're on your own if you want to preserve your changes and also re-generate scaffold after adding fields.
5
+ Using Turbo-Rails and Hotwire you get a lightning-fast out-of-the-box CRUD building experience. Every page displays only a list view: new and edit operations happen as 'edit-in-place', so the user never leaves the page.
6
6
 
7
- It gives users full control over objects they 'own' and by default it spits out functionality giving access to all fields.
7
+ It will read your relationships and field types to generate your code for you, leaving you with a 'sourdough starter' to work from. If you modify the generated code, you're on your own if you want to preserve your changes and also re-generate scaffold after adding fields.
8
8
 
9
- Hot Glue generates functionality that's quick and dirty. It let's you be crafty. As with a real glue gun, take care not to burn yourself while using it.
9
+ By default, it generates code that gives users full control over objects they 'own' and by default it spits out functionality giving access to all fields.
10
10
 
11
- * Build plug-and-play scaffolding mixing HAML and turbo_stream responses
12
- * Automatically Reads Your Models (make them before building your scaffolding!)
13
- * CRUD, lists with pagination, (coming soon: sorting & searching)
14
- * Wonderful for prototyping.
15
- * Nest your routes model-by-model for built-in poor man's authentication.
11
+ Hot Glue generates functionality that's quick and dirty. It let's you be crafty. As with a real hot glue gun, use with caution.
12
+
13
+ * Build plug-and-play scaffolding for any CRUD on any object
14
+ * mixes HAML and turbo_stream responses
15
+ * Everything edits-in-place (unless you use --big-edit, then it won't)
16
+ * Automatically reads your ActiveRecord models and relationships (make them before building your scaffolding!)
17
+ * Create-read-update-delete (CRUD) with pagination (one day: sorting & searching)
18
+ * Excellent tool for prototyping and hackathons, but a knowledge of Rails is needed.
19
+ * Nest your routes model-by-model for built-in poor man's authentication. (Customers have_many :invoices; Invoices have_many :line_items; etc)
16
20
  * Plays nicely with Devise, but you can implement your own current_user object instead.
17
- * Requires & uses Kaminari for pagination.
18
- * Create specs automatically along with the controllers (* rspec only for now).
21
+ * Kaminari for pagination.
22
+ * Create specs automatically along with the controllers.
19
23
  * Throw the scaffolding away when your app is ready to graduate to its next phase (or don't if you like it).
20
24
 
21
- ## QUICK START (COMING SOON)
25
+ ## QUICK START
22
26
 
23
27
  It's really easy to get started by following along with this blog post that creates three simple tables (User, Event, and Format).
24
28
 
25
29
  Feel free to build your own tables when you get to the sections for building the 'Event' scaffold:
26
30
 
27
- https://blog.jasonfleetwoodboldt.com/hot-glue
31
+ https://jasonfleetwoodboldt.com/hot-glue
28
32
 
29
33
  ## HOW EASY?
30
34
 
31
-
32
35
  ```
33
36
  rails generate hot_glue:scaffold Thing
34
37
  ```
35
38
 
39
+ Generate a quick scaffold to manage a table called `pronouns`
40
+ ![hot-glue-3](https://user-images.githubusercontent.com/59002/116405509-bdee2f00-a7fd-11eb-9723-4c6e22f81bd3.gif)
41
+
42
+
43
+
44
+ Instantly get a simple CRUD interface
45
+
46
+ ![hot-glue-4](https://user-images.githubusercontent.com/59002/116405517-c2b2e300-a7fd-11eb-8423-d43e3afc9fa6.gif)
47
+
48
+
36
49
  ## TO INSTALL
37
50
 
38
- - Add Turbo-Rails to your Gemfile & bundle install, then install it with `rails turbo:install`
51
+ - Add `gem 'turbo-rails'` to your Gemfile & `bundle install`
52
+
53
+ - Then install it with `rails turbo:install`
39
54
 
40
55
  - The Turbo install has switched your action cable settings from 'async' to Redis, so be sure to start a redis server
41
56
 
42
- - Add hot_glue to your Gemfile & bundle install, then install it with `rails generate hot_glue:install`
57
+ - Add `gem 'hot-glue'` to your Gemfile & `bundle install`
58
+
59
+ - Run the hot-glue installation with `rails generate hot_glue:install`
43
60
 
44
61
  - Add to your `application.html.erb`
45
62
  ```
46
63
  <%= render partial: 'layouts/flash_notices' %>
47
64
  ```
48
65
 
66
+ - Rspec setup
67
+ - add `gem 'rspec-rails'` to your gemfile inside :development and :test
68
+ - add `gem 'factory_bot_rails'` to your gemfile inside :development and :test
69
+ - run `rails generate rspec:install`
70
+ - configure Rspec to work with Factory Bot inside of `rails_helper.rb`
71
+ ```
72
+ RSpec.configure do |config|
73
+ // ... more rspec configuration (not shown)
74
+ config.include FactoryBot::Syntax::Methods
75
+ end
76
+ ```
77
+ more info:
78
+ https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#rspec
79
+
80
+ - for a quick Capybara login, create a support helper in `spec/support/` and log-in as your user
81
+ ```
82
+ def login_as(account)
83
+ visit '/accounts/sign_in'
84
+ within("#new_account") do
85
+ fill_in 'Email', with: account.email
86
+ fill_in 'Password', with: 'password'
87
+ end
88
+ click_button 'Log in'
89
+ end
90
+ ```
91
+
49
92
  - Install Bootstrap (optional)
50
93
 
51
94
  Bootstrap with Webpack:
52
95
  - change `stylesheet_link_tag` to `stylesheet_pack_tag` in your application layout
53
- - `yarn add bootstrap`
54
- - create a new file at `app/javascript/css/site.scss` with this content
96
+ - run `yarn add bootstrap`
97
+ - create a new file at `app/javascript/require_bootstrap.scss` with this content
55
98
  ```
56
99
  @import "~bootstrap/scss/bootstrap.scss";
57
100
  ```
58
101
 
59
102
  - add to `app/javascript/packs/application.js`
60
103
  ```
61
- import 'css/site'
104
+ import 'require_bootstrap'
62
105
  ```
63
106
 
64
107
  Bootstrap with Sprockets:
65
- - use bootstrap-rails gem
66
-
108
+ - use bootstrap-rubygem gem
109
+ - see README for bootstrap-rubygem to install
110
+
67
111
 
68
112
  - Install Devise or implement your own authentication
113
+ (or only use --gd mode, see below)
69
114
 
115
+ - font-awesome
70
116
 
71
117
 
72
118
  ### First Argument
@@ -225,7 +271,7 @@ Please note that this example would product non-functional code, so you would ne
225
271
 
226
272
  ### `--plural=`
227
273
 
228
- You don't need this if the pluralized version is just + "s" of the singular version. Only use for non-standard plurlizations, and be sure to pass it as TitleCase (as if you pluralized the model name)
274
+ You don't need this if the pluralized version is just + "s" of the singular version. Only use for non-standard plurlizations, and be sure to pass it as TitleCase (as if you pluralized the model name which is non-standard for Rails)
229
275
 
230
276
 
231
277
  ### `--exclude=`
@@ -249,13 +295,22 @@ You may not specify both include and exclude. If you specify an include list, it
249
295
  `rails generate hot_glue:scaffold Account --include=first_name,last_name,company_name,created_at,kyc_verified_at`
250
296
 
251
297
 
298
+ ### `--show-only=`
299
+ (separate field names by COMMA)
300
+
301
+ Any fields only the 'show-only' list will appear as non-editable on the generate form. (visible only)
302
+
303
+ IMPORTANT: By default, all fields that begin with an underscore (`_`) are automatically show-only.
304
+
305
+ I would recommend this for fields you want globally non-editable by users in your app. For example, a counter cache or other field set only by a backend mechanism.
306
+
252
307
  ### `--god` or `--gd`
253
308
 
254
309
  Use this flag to create controllers with no root authentication. You can still use an auth_identifier, which can be useful for a meta-leval authentication to the controller.
255
310
 
256
311
  For example, FOR ADMIN CONTROLLERS ONLY, supply a auth_identifier and use `--god` flag.
257
312
 
258
- In God mode, the objects are loaded directly from the base class (these controllers have full access)
313
+ In Gd mode, the objects are loaded directly from the base class (these controllers have full access)
259
314
  ```
260
315
  def load_thing
261
316
  @thing = Thing.find(params[:id])
@@ -295,8 +350,19 @@ If you do not want inline editing of your list items but instead to fall back to
295
350
 
296
351
 
297
352
 
353
+
354
+
298
355
  # VERSION HISTORY
299
356
 
357
+ #### - v0.1.1 -
358
+
359
+
360
+ #### 2021-04-28 - v0.1.0 - Very pleased to introduce full behavior specs, found in specs/system/, generated by default on all build code; also many fixes involving nesting and authentication"
361
+
362
+ #### 2021-03-24 - v0.0.9 - fixes in the automatic field label detection; cleans up junk in spec output
363
+
364
+ #### 2021-03-21 - v0.0.8 - show only flag; more specific spec coverage in generator spec
365
+
300
366
  #### 2021-03-20 - v0.0.7 - adds lots of spec coverage; cleans up generated cruft code on each run; adds no-delete, no-create; a working --big-edit with basic data-turbo false to disable inline editing
301
367
 
302
368
  #### 2021-03-06 - v0.0.6 - internal specs test the error catches and cover basic code generation (dummy testing only)
@@ -314,41 +380,19 @@ If you do not want inline editing of your list items but instead to fall back to
314
380
  #### 2021-02-23 - v0.0.0 - Port of my prior work from github.com/jasonfb/common_core_js
315
381
 
316
382
 
317
- # ACKNOWLEDGEMENTS
318
-
319
- ### "POOR MAN"
320
-
321
- I hope one day I will leave this Earth a poor man (like my code) owning only the most simple structure for the simple form of my existence. Thanks for having educated me in this wisdom goes to my former mentor [@trak3r](https://github.com/trak3r)!
322
-
323
-
324
-
325
383
 
326
384
  # HOW THIS GEM IS TESTED
327
385
 
328
- The testing of functionality-within-functionality is a little tricky and requires thinking outside the box.
386
+ SETUP:
387
+ • Run bundle install
388
+ • if you can't get through see https://stackoverflow.com/questions/68050807/gem-install-mimemagic-v-0-3-10-fails-to-install-on-big-sur/68170982#68170982
329
389
 
330
- We have two kinds of "sandboxes": a DUMMY sandbox, and also a STRAWMAN sandbox
331
390
 
332
391
  The dummy sandbox is found at `spec/dummy`
333
392
 
334
- The dummy lives as mostly checked- into the repository, except the folders where the generated code goes (`spec/dummy/app/views/`, `spec/dummy/app/controllers/`, `spec/dummy/specs/` are excluded from Git)
393
+ The dummy sandbox lives as mostly checked- into the repository, **except** the folders where the generated code goes (`spec/dummy/app/views/`, `spec/dummy/app/controllers/`, `spec/dummy/specs/` are excluded from Git)
335
394
 
336
395
  When you run the **internal specs**, which you can do **at the root of this repo** using the command `rspec`, a set of specs will run to assert the generators are erroring when they are supposed to and producing code when they are supposed to.
337
396
 
338
-
339
397
  The DUMMY testing DOES NOT test the actual functionality of the output code (it just tests the functionality of the generation process).
340
398
 
341
- For this reason, I've also added something I call STRAWMAN testing, which is a set of steps that does these things:
342
-
343
- The Strawman isn't in the repository, but if you build it locally, it will create itself into
344
-
345
- `spec/strawman/`
346
-
347
- 1) Builds you a strawman sandbox app from scratch, using the native `rails new`
348
- 2) Makes a few small modifications to the new app to support this gem
349
- 3) Create two nonsense tables called OmnitableA and OmnitableB. Each omnitable has one of each kind of field (integer, text, string, date, time, etc)
350
- 4) In this way, it is a "Noah's Arc" testing strategy: It will build you a fully functional app using all of the feature sets of the gem.
351
- 5) The built app itself will contain its own specs
352
- 6) You will then cd into `spec/strawman` and run `rspec`. This second test suite now runs to full test all of the *generated* code.
353
-
354
-
@@ -0,0 +1,9 @@
1
+ class CreateGhis < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :ghis do |t|
4
+ t.integer :def_id
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
data/db/schema.rb CHANGED
@@ -27,7 +27,7 @@ ActiveRecord::Schema.define(version: 2021_03_06_225506) do
27
27
  t.datetime "updated_at", precision: 6, null: false
28
28
  end
29
29
 
30
- create_table "hgis", force: :cascade do |t|
30
+ create_table "ghis", force: :cascade do |t|
31
31
  t.integer "def_id"
32
32
  t.datetime "created_at", precision: 6, null: false
33
33
  t.datetime "updated_at", precision: 6, null: false
@@ -3,13 +3,31 @@ require 'ffaker'
3
3
 
4
4
 
5
5
  module HotGlue
6
-
7
-
8
6
  class Error < StandardError
9
7
  end
10
8
 
11
-
12
9
  module GeneratorHelper
10
+ def derrive_reference_name thing_as_string
11
+ assoc_class = eval(thing_as_string)
12
+
13
+ if assoc_class.respond_to?("name")
14
+ display_column = "name"
15
+ elsif assoc_class.respond_to?("to_label")
16
+ display_column = "to_label"
17
+ elsif assoc_class.respond_to?("full_name")
18
+ display_column = "full_name"
19
+ elsif assoc_class.respond_to?("display_name")
20
+ display_column = "display_name"
21
+ elsif assoc_class.respond_to?("email")
22
+ display_column = "email"
23
+ else
24
+ raise("this should have been caught by the checker in the initializer")
25
+ # puts "*** Oops: Can't find any column to use as the display label for the #{assoc.name.to_s} association on the #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, or 5) email directly on your #{assoc.class_name} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
26
+ end
27
+ display_column
28
+ end
29
+
30
+
13
31
  def text_area_output(col, field_length, col_identifier )
14
32
  lines = field_length % 40
15
33
  if lines > 5
@@ -55,12 +73,13 @@ module HotGlue
55
73
  class_option :include, type: :string, default: ""
56
74
  class_option :god, type: :boolean, default: false
57
75
  class_option :gd, type: :boolean, default: false # alias for god
58
- class_option :spacs_only, type: :boolean, default: false
76
+ class_option :specs_only, type: :boolean, default: false
59
77
  class_option :no_specs, type: :boolean, default: false
60
78
  class_option :no_delete, type: :boolean, default: false
61
79
  class_option :no_create, type: :boolean, default: false
62
80
  class_option :no_paginate, type: :boolean, default: false
63
81
  class_option :big_edit, type: :boolean, default: false
82
+ class_option :show_only, type: :string, default: ""
64
83
 
65
84
  def initialize(*meta_args) #:nodoc:
66
85
  super
@@ -81,21 +100,32 @@ module HotGlue
81
100
  @singular = args.first.tableize.singularize # should be in form hello_world
82
101
  @plural = options['plural'] || @singular + "s" # supply to override; leave blank to use default
83
102
  @auth = options['auth'] || "current_user"
84
- @auth_identifier = options['auth'] || (!@auth.nil? && @auth.gsub("current_", "")) || nil
85
- @nest = options['auth'] || nil
103
+ @auth_identifier = options['auth_identifier'] || (!@auth.nil? && @auth.gsub("current_", "")) || nil
104
+
105
+
106
+ @nest = (!options['nest'].empty? && options['nest']) || nil
86
107
  @namespace = options['namespace'] || nil
108
+
87
109
  @singular_class = @singular.titleize.gsub(" ", "")
88
110
  @exclude_fields = []
89
111
  @exclude_fields += options['exclude'].split(",").collect(&:to_sym)
90
112
 
91
- if options['include']
113
+ if !options['include'].empty?
92
114
  @include_fields = []
93
115
  @include_fields += options['include'].split(",").collect(&:to_sym)
94
116
  end
117
+
118
+
119
+ @show_only = []
120
+ if !options['show_only'].empty?
121
+ @show_only += options['show_only'].split(",").collect(&:to_sym)
122
+ end
123
+
95
124
  auth_assoc = @auth.gsub("current_","")
96
125
 
97
126
  @god = options['god'] || options['gd'] || false
98
127
  @specs_only = options['specs_only'] || false
128
+
99
129
  @no_specs = options['no_specs'] || false
100
130
  @no_delete = options['no_delete'] || false
101
131
 
@@ -145,17 +175,29 @@ module HotGlue
145
175
 
146
176
  if assoc
147
177
  ownership_field = assoc.name.to_s + "_id"
178
+ elsif !@nest
179
+ exit_message = "*** Oops: It looks like is no association from current_#{@object_owner_sym} to a class called #{@singular_class}. If your user is called something else, pass with flag auth=current_X where X is the model for your users as lowercase. Also, be sure to implement current_X as a method on your controller. (If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for auth_identifier.) To make a controller that can read all records, specify with --god."
180
+
148
181
  else
149
- # if @auth
150
- exit_message= "*** Oops: It looks like is no association from current_#{@object_owner_sym} to a class called #{singular_class}. If your user is called something else, pass with flag auth=current_X where X is the model for your users as lowercase. Also, be sure to implement current_X as a method on your controller. (If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for auth_identifier.) To make a controller that can read all records, specify with --god."
151
- # else
152
- # exit_message= "*** Oops: god mode could not find the association(?). something is wrong."
153
- # end
182
+ if @god
183
+
184
+ exit_message= "*** Oops: god mode could not find the association(?). something is wrong."
185
+ else
186
+ @auth_check = "current_user"
187
+ @nested_args.each do |arg|
188
+
189
+ if !@auth_check.method("#{arg}s")
190
+ exit_message= "*** Oops: your nesting chain does not have a assocation for #{arg}s on #{@auth_check} something is wrong."
191
+ end
192
+ byebug
193
+ puts ""
194
+ end
195
+ end
196
+
154
197
  raise(HotGlue::Error, exit_message)
155
198
  end
156
199
  end
157
200
 
158
-
159
201
  if !@include_fields
160
202
  @exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
161
203
  :reset_password_token,
@@ -174,9 +216,11 @@ module HotGlue
174
216
 
175
217
  end
176
218
 
177
-
178
-
179
219
  @columns.each do |col|
220
+ if col.to_s.starts_with?("_")
221
+ @show_only << col
222
+ end
223
+
180
224
  if object.columns_hash[col.to_s].type == :integer
181
225
  if col.to_s.ends_with?("_id")
182
226
  # guess the association name label
@@ -187,7 +231,7 @@ module HotGlue
187
231
  begin
188
232
  eval(assoc.class_name)
189
233
  rescue NameError => e
190
- exit_message = "*** Oops: The table #{singular_class} has an association for '#{assoc.name.to_s}', but I can't find an assoicated model for that association. TODO: Please implement a model for #{assoc.name.to_s} that belongs to #{singular_class} "
234
+ exit_message = "*** Oops: The model #{singular_class} is missing an association for #{assoc_name} or the model doesn't exist. TODO: Please implement a model for #{assoc_name.titlecase}; your model #{singular_class.titlecase} should have_many :#{assoc_name}s. To make a controller that can read all records, specify with --god."
191
235
  raise(HotGlue::Error, exit_message)
192
236
 
193
237
  end
@@ -199,18 +243,16 @@ module HotGlue
199
243
  end
200
244
 
201
245
  assoc_class = eval(assoc.class_name)
202
- if assoc_class.column_names.include?("name")
203
- # display_column = "name"
204
- elsif assoc_class.column_names.include?("to_label")
205
- # display_column = "to_label"
206
- elsif assoc_class.column_names.include?("full_name")
207
- # display_column = "full_name"
208
- elsif assoc_class.column_names.include?("display_name")
209
- # display_column = "display_name"
210
- elsif assoc_class.column_names.include?("email")
211
- # display_column = "email"
246
+
247
+ name_list = [:name, :to_label, :full_name, :display_name, :email]
248
+
249
+
250
+ if name_list.collect{ |field|
251
+ assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
252
+ }.any?
253
+ # do nothing here
212
254
  else
213
- exit_message= "*** Oops: Can't find any column to use as the display label for the #{assoc.name.to_s} association on the #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, or 5) email directly on your #{assoc.class_name} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
255
+ exit_message= "*** Oops: Missing a label for #{assoc.class_name.upcase}. Can't find any column to use as the display label for the #{assoc.name.to_s} association on the #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, or 5) email directly on your #{assoc.class_name.upcase} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
214
256
  raise(HotGlue::Error,exit_message)
215
257
  end
216
258
  end
@@ -234,15 +276,18 @@ module HotGlue
234
276
 
235
277
  unless @specs_only
236
278
  template "controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
237
- if @namespace && defined?(controller_descends_from) == nil
238
- template "base_controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "base_controller.rb")
279
+ if @namespace
280
+ begin
281
+ eval(controller_descends_from)
282
+ puts " skipping base controller #{controller_descends_from}"
283
+ rescue NameError => e
284
+ template "base_controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "base_controller.rb")
285
+ end
239
286
  end
240
287
  end
241
288
 
242
289
  unless @no_specs
243
- template "request_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/request#{namespace_with_dash}", "#{plural}_spec.rb")
244
- template "system_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_spec.rb")
245
-
290
+ template "system_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
246
291
  end
247
292
 
248
293
  template "_errors.haml", File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", "_errors.haml")
@@ -321,9 +366,9 @@ module HotGlue
321
366
  end
322
367
 
323
368
 
324
- def path_helper_full
325
- "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{singular}_path"
326
- end
369
+ # def path_helper_full
370
+ # "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{singular}_path"
371
+ # end
327
372
 
328
373
  def path_helper_args
329
374
  if @nested_args.any?
@@ -435,6 +480,9 @@ module HotGlue
435
480
  end
436
481
 
437
482
 
483
+
484
+
485
+
438
486
  def copy_view_files
439
487
  return if @specs_only
440
488
  haml_views.each do |view|
@@ -504,6 +552,16 @@ module HotGlue
504
552
  col_spaces_prepend = " "
505
553
 
506
554
  res = @columns.map { |col|
555
+
556
+ if @show_only.include?(col)
557
+
558
+ "#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
559
+ = @#{singular}.#{col.to_s}
560
+ %label.form-text
561
+ #{col.to_s.humanize}\n"
562
+ else
563
+
564
+
507
565
  type = eval("#{singular_class}.columns_hash['#{col}']").type
508
566
  limit = eval("#{singular_class}.columns_hash['#{col}']").limit
509
567
  sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
@@ -512,36 +570,17 @@ module HotGlue
512
570
  when :integer
513
571
  # look for a belongs_to on this object
514
572
  if col.to_s.ends_with?("_id")
515
- # # guess the association name label
516
- #
517
- #
518
- # assoc_name = col.to_s.gsub("_id","")
519
- # assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
520
- # if assoc.nil?
521
- # exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
522
- # exit
523
- # end
524
-
525
-
526
- assoc_class = eval(assoc.class_name)
527
-
528
- if assoc_class.column_names.include?("name")
529
- display_column = "name"
530
- elsif assoc_class.column_names.include?("to_label")
531
- display_column = "to_label"
532
- elsif assoc_class.column_names.include?("full_name")
533
- display_column = "full_name"
534
- elsif assoc_class.column_names.include?("display_name")
535
- display_column = "display_name"
536
- elsif assoc_class.column_names.include?("email")
537
- display_column = "email"
538
- else
539
- raise("this should have been caught by the checker in the initializer")
540
- # puts "*** Oops: Can't find any column to use as the display label for the #{assoc.name.to_s} association on the #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, or 5) email directly on your #{assoc.class_name} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
573
+ assoc_name = col.to_s.gsub("_id","")
574
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
575
+ if assoc.nil?
576
+ exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
577
+ exit
541
578
  end
579
+ display_column = derrive_reference_name(assoc.class_name)
580
+
542
581
 
543
582
  "#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{assoc_name.to_s})}\"}
544
- #{col_spaces_prepend}= f.collection_select(:#{col.to_s}, #{assoc_class}.all, :id, :#{display_column}, {prompt: true, selected: @#{singular}.#{col.to_s} }, class: 'form-control')
583
+ #{col_spaces_prepend}= f.collection_select(:#{col.to_s}, #{assoc.class_name}.all, :id, :#{display_column}, {prompt: true, selected: @#{singular}.#{col.to_s} }, class: 'form-control')
545
584
  #{col_spaces_prepend}%label.small.form-text.text-muted
546
585
  #{col_spaces_prepend} #{col.to_s.humanize}"
547
586
 
@@ -591,7 +630,7 @@ module HotGlue
591
630
  #{col_spaces_prepend}= f.label(:#{col.to_s}, value: 'Yes', for: '#{singular}_#{col.to_s}_1')
592
631
  "
593
632
  end
594
-
633
+ end
595
634
  }.join("\n")
596
635
  return res
597
636
  end
@@ -621,25 +660,9 @@ module HotGlue
621
660
  exit_message = "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
622
661
  raise(HotGlue::Error,exit_message)
623
662
  end
624
-
625
- assoc_class = eval(assoc.class_name)
626
663
 
627
- if assoc_class.column_names.include?("name")
628
- display_column = "name"
629
- elsif assoc_class.column_names.include?("to_label")
630
- display_column = "to_label"
631
- elsif assoc_class.column_names.include?("full_name")
632
- display_column = "full_name"
633
- elsif assoc_class.column_names.include?("display_name")
634
- display_column = "display_name"
635
- elsif assoc_class.column_names.include?("email")
636
- display_column = "email"
637
- elsif assoc_class.column_names.include?("number")
638
- display_column = "number"
664
+ display_column = derrive_reference_name(assoc.class_name)
639
665
 
640
- else
641
- puts "*** Oops: Can't find any column to use as the display label for the #{assoc.name.to_s} association on the #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, 5) email, or 6) number directly on your #{assoc.class_name} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
642
- end
643
666
 
644
667
  "#{col_identifer}
645
668
  = #{singular}.#{assoc.name.to_s}.try(:#{display_column}) || '<span class=\"content alert-danger\">MISSING</span>'.html_safe"
@@ -713,19 +736,20 @@ module HotGlue
713
736
  me = eval(singular_class)
714
737
 
715
738
  @display_class ||=
716
- if me.respond_to?("name")
739
+ if me.column_names.include?("name") || me.instance_methods(false).include?(:name)
740
+ # note that all class object respond_to?(:name) with the name of their own class
741
+ # this one is unique
717
742
  "name"
718
- elsif me.respond_to?("to_label")
743
+ elsif me.column_names.include?("to_label") || me.instance_methods(false).include?(:to_label)
719
744
  "to_label"
720
- elsif me.respond_to?("full_name")
745
+ elsif me.column_names.include?("full_name") || me.instance_methods(false).include?(:full_name)
721
746
  "full_name"
722
- elsif me.respond_to?("display_name")
747
+ elsif me.column_names.include?("display_name") || me.instance_methods(false).include?(:display_name)
723
748
  "display_name"
724
- elsif me.respond_to?("email")
749
+ elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
725
750
  "email"
726
- elsif me.respond_to?("number")
727
- display_column = "number"
728
-
751
+ elsif me.column_names.include?("number") || me.instance_methods(false).include?(:number)
752
+ "number"
729
753
  else
730
754
  exit_message = "*** Oops: Can't find any column to use as the display label on #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, 5) email, or 6) number directly on your #{singular_class} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
731
755
  raise(HotGlue::Error, exit_message)
@@ -753,7 +777,8 @@ module HotGlue
753
777
 
754
778
 
755
779
  def paginate
756
- "= paginate #{plural}"
780
+ "- if #{plural}.respond_to?(:total_pages)
781
+ = paginate #{plural}"
757
782
  end
758
783
 
759
784
  private # thor does something fancy like sending the class all of its own methods during some strange run sequence
@@ -1,4 +1,5 @@
1
1
  .row
2
2
  <%= all_form_fields %>
3
3
  .col
4
+ = link_to "Cancel", <%= path_helper_plural %>, {class: "btn btn-secondary"}
4
5
  = f.submit "Save", class: "btn btn-primary pull-right"
@@ -5,6 +5,3 @@
5
5
  = form_with model: <%= singular %>, url: <%= path_helper_plural %>(<%= nested_objects_arity %>), method: "post" do |f|
6
6
  = render partial: "<%=namespace_with_slash%><%= @plural %>/form", locals: {<%= singular %>: <%= singular %>, f: f}
7
7
 
8
- .row
9
- .col-md-12
10
- = f.submit "Save", class: "btn btn-primary pull-right"
@@ -1,7 +1,7 @@
1
1
  <%= all_line_fields %>
2
2
  .col
3
3
  <% if destroy_action %>
4
- = link_to "Delete <i class='fa fa-1x fa-remove'></i>".html_safe, <%= path_helper_full %>(<%= path_helper_args %>), method: :delete, data: {confirm: 'Are you sure?'}, disable_with: "Loading...", class: "delete-<%= singular %>-button btn btn-primary "
4
+ = link_to "Delete <i class='fa fa-1x fa-remove'></i>".html_safe, <%= path_helper_singular %>(<%= path_helper_args %>), method: :delete, data: {confirm: 'Are you sure?'}, disable_with: "Loading...", class: "delete-<%= singular %>-button btn btn-primary "
5
5
  <% end %>
6
6
  &nbsp;
7
- = link_to "Edit <i class='fa fa-1x fa-list-alt'></i>".html_safe, edit_<%= path_helper_full %>(<%= path_helper_args %>), <% if @big_edit %>'data-turbo' => 'false', <% end %>disable_with: "Loading...", class: "edit-<%= singular %>-button btn btn-primary "
7
+ = link_to "Edit <i class='fa fa-1x fa-list-alt'></i>".html_safe, edit_<%= path_helper_singular %>(<%= path_helper_args %>), <% if @big_edit %>'data-turbo' => 'false', <% end %>disable_with: "Loading...", class: "edit-<%= singular %>-button btn btn-primary "
@@ -1,7 +1,6 @@
1
1
  class <%= controller_class_name %> < <%= controller_descends_from %>
2
2
  <% unless @auth_identifier == '' || @auth.nil? %>before_action :authenticate_<%= @auth_identifier %>!<% end %>
3
- <% if any_nested? %> <% @nested_args.each do |arg| %>
4
- before_action :load_<%= arg %><% end %> <% end %>
3
+
5
4
  before_action :load_<%= singular_name %>, only: [:show, :edit, :update, :destroy]
6
5
  helper :hot_glue
7
6
  include HotGlue::ControllerHelper
@@ -11,22 +10,23 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
11
10
  <% end %>
12
11
 
13
12
  <% if any_nested? %><% nest_chain = [] %> <% @nested_args.each { |arg|
14
- this_scope = nest_chain.empty? ? "#{@auth ? auth_object : class_name}.#{arg}s" : "@#{nest_chain.last}.#{arg}s"
15
- nest_chain << arg %>def load_<%= arg %>
16
- @<%= arg %> = <%= this_scope %>.find(params[:<%= arg %>_id])
13
+ this_scope = nest_chain.empty? ? "#{@auth ? auth_object : class_name}.#{arg}s" : "#{nest_chain.last}.#{arg}s"
14
+ nest_chain << arg %>
15
+ def <%= arg %>
16
+ @<%= arg %> ||= <%= this_scope %>.find(params[:<%= arg %>_id])
17
17
  end<% } %><% end %>
18
18
 
19
19
  <% if !@self_auth %>
20
20
  def load_<%= singular_name %>
21
- @<%= singular_name %> = <%= object_scope %>.find(params[:id])
21
+ @<%= singular_name %> = <%= object_scope.gsub("@",'') %>.find(params[:id])
22
22
  end
23
23
  <% else %>
24
24
  def load_<%= singular_name %>
25
- @<%= singular_name %> = <%= auth_object %>
25
+ @<%= singular_name %> = <%= auth_object.gsub("@",'') %>
26
26
  end<% end %>
27
27
 
28
28
  def load_all_<%= plural %>
29
- <% if !@self_auth %>@<%= plural_name %> = <%= object_scope %><% if model_has_strings? %>.where(<%=class_name %>.arel_table[:email].matches("%#{@__general_string}%"))<% end %>.page(params[:page])
29
+ <% if !@self_auth %>@<%= plural_name %> = <%= object_scope.gsub("@",'') %><% if model_has_strings? %>.where(<%=class_name %>.arel_table[:email].matches("%#{@__general_string}%"))<% end %>.page(params[:page])
30
30
  <% else %>@<%= plural_name %> = [<%= auth_object %>]<% end %>
31
31
  end
32
32
 
@@ -81,8 +81,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
81
81
  end
82
82
 
83
83
  def update
84
- if !@<%= singular_name %>.update(modify_date_inputs_on_params(<%= singular %>_params<%= @auth ? ', ' + @auth : '' %>))
85
- flash[:alert] = "<%= singular_name.titlecase %> could not be saved"
84
+ if @<%= singular_name %>.update(modify_date_inputs_on_params(<%= singular %>_params<%= @auth ? ', ' + @auth : '' %>))
85
+ flash[:notice] = "Saved #{@<%= singular %>.<%= display_class %>}"
86
+ else
87
+ flash[:alert] = "<%= singular_name.titlecase %> could not be saved."
86
88
  end
87
89
  respond_to do |format|
88
90
  format.turbo_stream
@@ -1,108 +1,147 @@
1
1
  require 'rails_helper'
2
2
 
3
3
  describe "interaction for <%= controller_class_name %>", type: :feature do
4
- <% unless @auth.nil? %> let(:<%= @auth %>) {create(:<%= @auth.gsub('current_', '') %>)}<%end%>
5
- let(:<%= singular %>) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> )}
4
+ include HotGlue::ControllerHelper
5
+ <% unless @auth.nil? %>let(:<%= @auth %>) {create(:<%= @auth.gsub('current_', '') %>)}<%end%>
6
6
 
7
- <%= objest_nest_factory_setup %>
7
+ let!(:<%= singular %>1) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> )}
8
+ let!(:<%= singular %>2) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> )}
9
+ let!(:<%= singular %>3) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> )}
8
10
 
9
- before(:each) do
10
- @request.env["devise.mapping"] = Devise.mappings[:account]
11
+ <%= objest_nest_factory_setup %>
11
12
 
12
- sign_in <%= @auth %>, scope: :<%= @auth %>
13
+ before(:each) do
14
+ login_as(<%= @auth %>)
13
15
  end
14
16
 
15
17
  describe "index" do
16
- it "should respond" do
17
- get :index, xhr: true, format: 'js', params: {
18
- <%= objest_nest_params_by_id_for_specs %>
19
- }
20
- end
18
+ it "should show me the list" do
19
+ visit <%= path_helper_plural %>
20
+
21
+ <%=
22
+ @columns.map { |col|
23
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
24
+ # limit = eval("#{singular_class}.columns_hash['#{col}']").limit
25
+ # sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
26
+ #
27
+
28
+ case type
29
+ when :datetime
30
+ " " + ["expect(page).to have_content(#{singular}#{rand(3)+1}.#{col}.in_time_zone(#{ @auth }.timezone).strftime('%m/%d/%Y @ %l:%M %p ').gsub(' ', ' ') + timezonize(#{ @auth }.timezone) )"].join("\n ")
31
+
32
+ else
33
+ " " + ["expect(page).to have_content(#{singular}#{rand(3)+1}.#{col})"].join("\n ")
34
+
21
35
  end
22
36
 
23
- describe "new" do
24
- it "should show form" do
25
- get :new, xhr: true, format: 'js', params: {
26
- <%= objest_nest_params_by_id_for_specs %>
27
- }
37
+ }.join("\n")
38
+
39
+ %>
40
+
28
41
  end
29
42
  end
30
43
 
31
- describe "create" do
32
- it "should create a new <%= singular %>" do
33
- expect {
34
- post :create, xhr: true, format: 'js', params: {
35
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
36
- <%= singular %>: {
37
- <%= columns_spec_with_sample_data %>
38
- }}
39
- }.to change { <%= @singular_class %>.all.count }.by(1)
40
- assert_response :ok
41
- end
44
+ describe "new & create" do
45
+ it "should create a new <%= singular.titlecase %>" do
46
+ visit <%= path_helper_plural %>
47
+ click_link "New <%= singular.titlecase %>"
48
+ expect(page).to have_selector(:xpath, './/h3[contains(., "New <%= singular.titlecase %>")]')
42
49
 
43
- # it "should not create if there are errors" do
44
- # post :create, xhr: true, format: 'js', params: {id: <%= singular %>.id,
45
- # <%= singular %>: {skin_id: nil}}
50
+ <%=
51
+ @columns.map { |col|
52
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
53
+ # limit = eval("#{singular_class}.columns_hash['#{col}']").limit
54
+ # sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
46
55
  #
47
- # expect(controller).to set_flash.now[:alert].to(/Oops, your <%= singular %> could not be saved/)
48
- # end
49
- end
50
56
 
51
- describe "edit" do
52
- it "should return an editable form" do
53
- get :edit, xhr: true, format: 'js', params: {
54
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
55
- id: <%= singular %>.id
56
- }
57
- assert_response :ok
57
+ case type
58
+ when :datetime
59
+ when :integer
60
+ " " + 'find("input#' + singular + '_' + col.to_s + '").fill_in(with: rand(10))'
61
+ else
62
+ " " + "new_#{col} = 'new_test-email@nowhere.com' \n" +
63
+ ' ' + 'find("input#' + singular + '_' + col.to_s + '").fill_in(with: new_' + col.to_s + ')'
64
+ end
65
+
66
+ }.join("\n")
67
+
68
+ %>
69
+ click_button "Save"
70
+ expect(page).to have_content("Successfully created")
71
+
72
+ <%=
73
+ @columns.map { |col|
74
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
75
+
76
+ case type
77
+ when :datetime
78
+ when :integer
79
+ else
80
+ "expect(page).to have_content(new_#{col})"
81
+ end
82
+
83
+ }.join("\n")
84
+ %>
85
+
58
86
  end
59
87
  end
60
88
 
61
89
  describe "show" do
62
90
  it "should return a view form" do
63
- get :show, xhr: true, format: 'js', params: {
64
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
65
- id: <%= singular %>.id
66
- }
67
- assert_response :ok
91
+ visit <%= path_helper_plural %>
92
+
68
93
  end
69
94
  end
70
95
 
71
- describe "update" do
72
- it "should update" do
73
- put :update, xhr: true, format: 'js',
74
- params: {
75
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
76
- id: <%= singular %>.id,
77
- <%= singular %>: {
78
- <%= columns_spec_with_sample_data %>
79
- }}
80
-
81
- assert_response :ok
82
- end
96
+ describe "edit & update" do
97
+ it "should return an editable form" do
98
+ visit <%= path_helper_plural %>
99
+ find("a.edit-<%= singular %>-button[href='/<%= namespace_with_slash %><%= plural %>/#{<%= singular %>1.id}/edit']").click
83
100
 
84
- # it "should not update if invalid" do
85
- # put :update, xhr: true, format: 'js',
86
- # params: {
87
- # id: <%= singular %>.id,
88
- # <%= singular %>: {
89
- # <%= columns_spec_with_sample_data %>
90
- # }}
91
- #
92
- # assert_response :ok
93
- #
94
- # expect(controller).to set_flash.now[:alert].to(/Oops, your <%= singular %> could not be saved/)
95
- # end
101
+ expect(page).to have_content("Editing #{<%= singular %>1.<%= derrive_reference_name(singular_class) %>}")
102
+ <%=
103
+ @columns.map { |col|
104
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
105
+
106
+ case type
107
+ when :datetime
108
+ when :integer
109
+ else
110
+ " " + "new_#{col.to_s} = Faker::Name.new \n" +
111
+
112
+ ' find("input[name=\'' + singular + '[' + col.to_s + ']\'").fill_in(with: new_' + col.to_s + ')'
113
+
114
+ end
115
+ }.join("\n")
116
+ %>
117
+ click_button "Save"
118
+ within("turbo-frame#<%= singular %>__#{<%= singular %>1.id} ") do
119
+
120
+
121
+ <%=
122
+ @columns.map { |col|
123
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
124
+ case type
125
+ when :datetime
126
+ when :integer
127
+ else
128
+ ' expect(page).to have_content(new_' + col.to_s + ')'
129
+ end
130
+ }.join("\n")
131
+ %>
132
+
133
+ end
134
+ end
96
135
  end
97
136
 
98
- describe "#destroy" do
137
+ describe "destroy" do
99
138
  it "should destroy" do
100
- post :destroy, format: 'js', params: {
101
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
102
- id: <%= singular %>.id
103
- }
104
- assert_response :ok
105
- expect(<%= @singular_class %>.count).to be(0)
139
+ visit <%= path_helper_plural %>
140
+ accept_alert do
141
+ find("a.delete-<%= singular %>-button[href='<%= namespace_with_dash %>/<%= plural %>/#{<%= singular %>1.id}']").click
142
+ end
143
+ expect(page).to_not have_content(<%= singular %>1.email)
144
+ expect(<%= singular_class %>.where(id: <%= singular %>1.id).count).to eq(0)
106
145
  end
107
146
  end
108
147
  end
@@ -3,3 +3,7 @@
3
3
  = render partial: 'line', locals: {<%= singular %>: @<%= singular %> <%= nested_assignments_with_leading_comma %> }
4
4
 
5
5
 
6
+ = turbo_stream.replace "flash_notices" do
7
+ = render partial: "layouts/flash_notices"
8
+ - if @<%= singular %>.errors.any?
9
+ = render partial: "errors", locals: {resource: @<%= singular %>}
@@ -1,3 +1,3 @@
1
1
  module HotGlue
2
- VERSION = '0.0.7'
2
+ VERSION = '0.1.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hot-glue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Fleetwood-Boldt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-20 00:00:00.000000000 Z
11
+ date: 2021-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -115,7 +115,7 @@ files:
115
115
  - config/database.yml
116
116
  - db/migrate/20210306212711_create_abcs.rb
117
117
  - db/migrate/20210306223300_create_defs.rb
118
- - db/migrate/20210306223305_create_hgis.rb
118
+ - db/migrate/20210306223305_create_ghis.rb
119
119
  - db/migrate/20210306223309_create_jkls.rb
120
120
  - db/migrate/20210306223701_devise_create_users.rb
121
121
  - db/migrate/20210306225506_create_xyzs.rb
@@ -138,7 +138,6 @@ files:
138
138
  - lib/generators/hot_glue/templates/edit.turbo_stream.haml
139
139
  - lib/generators/hot_glue/templates/index.haml
140
140
  - lib/generators/hot_glue/templates/new.haml
141
- - lib/generators/hot_glue/templates/request_spec.rb.erb
142
141
  - lib/generators/hot_glue/templates/system_spec.rb.erb
143
142
  - lib/generators/hot_glue/templates/update.turbo_stream.haml
144
143
  - lib/hot-glue.rb
@@ -149,8 +148,8 @@ licenses:
149
148
  - Nonstandard
150
149
  metadata:
151
150
  source_code_uri: https://github.com/jasonfb/hot-glue
152
- documentation_uri: https://jfb.teachable.com/p/gems-by-jason
153
- homepage_uri: https://blog.jasonfleetwoodboldt.com/hot-glue/
151
+ documentation_uri: https://www.instagram.com/jfbcodes/
152
+ homepage_uri: https://jasonfleetwoodboldt.com/hot-glue/
154
153
  post_install_message: |
155
154
  ---------------------------------------------
156
155
  Welcome to Hot Glue - A Scaffold Building Companion for Hotwire + Turbo-Rails
@@ -159,11 +158,11 @@ post_install_message: |
159
158
 
160
159
  * Build plug-and-play scaffolding mixing HAML with the power of Hotwire and Turbo-Rails
161
160
  * Automatically Reads Your Models (make them before building your scaffolding!)
162
- * Excellent for CRUD, lists with pagination, searching, sorting.
163
- * Great for prototyping very.
164
- * Plays nicely with Devise, Kaminari, Haml-Rails, Rspec.
165
- * Create specs automatically along with the controllers.
166
- * Nest your routes model-by-model for built-in poor man's authentication
161
+ * Excellent for CRUD, lists with pagination (coming soon: searching & sorting)
162
+ * Great for prototyping.
163
+ * Plays nicely with Devise, Kaminari, Haml-Rails, Rspec, FontAwesome
164
+ * Create specs automatically along with the generated controllers.
165
+ * Nest your routes model-by-model for built-in poor man's authentication.
167
166
  * Throw the scaffolding away when your app is ready to graduate to its next phase.
168
167
 
169
168
  see README for complete instructions.
@@ -182,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
181
  - !ruby/object:Gem::Version
183
182
  version: '0'
184
183
  requirements: []
185
- rubygems_version: 3.2.11
184
+ rubygems_version: 3.0.9
186
185
  signing_key:
187
186
  specification_version: 4
188
187
  summary: A gem build scaffolding.
@@ -1,9 +0,0 @@
1
- class CreateHgis < ActiveRecord::Migration[6.1]
2
- def change
3
- create_table :hgis do |t|
4
- t.integer :def_id
5
-
6
- t.timestamps
7
- end
8
- end
9
- end
@@ -1,110 +0,0 @@
1
- require 'rails_helper'
2
-
3
- describe <%= controller_class_name %> do
4
- render_views
5
- <% unless @auth.nil? %> let(:<%= @auth %>) {create(:<%= @auth.gsub('current_', '') %>)}<%end%>
6
- let(:<%= singular %>) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> )}
7
-
8
- <%= objest_nest_factory_setup %>
9
-
10
- before(:each) do
11
- @request.env["devise.mapping"] = Devise.mappings[:account]
12
-
13
- sign_in <%= @auth %>, scope: :<%= @auth %>
14
- end
15
-
16
- describe "index" do
17
- it "should respond" do
18
- get :index, xhr: true, format: 'js', params: {
19
- <%= objest_nest_params_by_id_for_specs %>
20
- }
21
- end
22
- end
23
-
24
- describe "new" do
25
- it "should show form" do
26
- get :new, xhr: true, format: 'js', params: {
27
- <%= objest_nest_params_by_id_for_specs %>
28
- }
29
- end
30
- end
31
-
32
- describe "create" do
33
- it "should create a new <%= singular %>" do
34
- expect {
35
- post :create, xhr: true, format: 'js', params: {
36
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
37
- <%= singular %>: {
38
- <%= columns_spec_with_sample_data %>
39
- }}
40
- }.to change { <%= @singular_class %>.all.count }.by(1)
41
- assert_response :ok
42
- end
43
-
44
- # it "should not create if there are errors" do
45
- # post :create, xhr: true, format: 'js', params: {id: <%= singular %>.id,
46
- # <%= singular %>: {skin_id: nil}}
47
- #
48
- # expect(controller).to set_flash.now[:alert].to(/Oops, your <%= singular %> could not be saved/)
49
- # end
50
- end
51
-
52
- describe "edit" do
53
- it "should return an editable form" do
54
- get :edit, xhr: true, format: 'js', params: {
55
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
56
- id: <%= singular %>.id
57
- }
58
- assert_response :ok
59
- end
60
- end
61
-
62
- describe "show" do
63
- it "should return a view form" do
64
- get :show, xhr: true, format: 'js', params: {
65
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
66
- id: <%= singular %>.id
67
- }
68
- assert_response :ok
69
- end
70
- end
71
-
72
- describe "update" do
73
- it "should update" do
74
- put :update, xhr: true, format: 'js',
75
- params: {
76
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
77
- id: <%= singular %>.id,
78
- <%= singular %>: {
79
- <%= columns_spec_with_sample_data %>
80
- }}
81
-
82
- assert_response :ok
83
- end
84
-
85
- # it "should not update if invalid" do
86
- # put :update, xhr: true, format: 'js',
87
- # params: {
88
- # id: <%= singular %>.id,
89
- # <%= singular %>: {
90
- # <%= columns_spec_with_sample_data %>
91
- # }}
92
- #
93
- # assert_response :ok
94
- #
95
- # expect(controller).to set_flash.now[:alert].to(/Oops, your <%= singular %> could not be saved/)
96
- # end
97
- end
98
-
99
- describe "#destroy" do
100
- it "should destroy" do
101
- post :destroy, format: 'js', params: {
102
- <%= (@nested_args.empty? ? "" : objest_nest_params_by_id_for_specs + ",") %>
103
- id: <%= singular %>.id
104
- }
105
- assert_response :ok
106
- expect(<%= @singular_class %>.count).to be(0)
107
- end
108
- end
109
- end
110
-