hot-glue 0.0.3 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -1
  3. data/.gitignore +12 -7
  4. data/Gemfile +4 -9
  5. data/Gemfile.lock +40 -23
  6. data/README.md +123 -31
  7. data/Rakefile +1 -1
  8. data/app/assets/config/manifest.js +0 -0
  9. data/bin/rails +2 -2
  10. data/config/database.yml +11 -0
  11. data/db/migrate/20210306212711_create_abcs.rb +11 -0
  12. data/db/migrate/20210306223300_create_defs.rb +9 -0
  13. data/db/migrate/20210306223305_create_hgis.rb +9 -0
  14. data/db/migrate/20210306223309_create_jkls.rb +9 -0
  15. data/db/migrate/20210306223701_devise_create_users.rb +44 -0
  16. data/db/migrate/20210306225506_create_xyzs.rb +9 -0
  17. data/db/schema.rb +60 -0
  18. data/lib/generators/hot_glue/install_generator.rb +3 -3
  19. data/lib/generators/hot_glue/scaffold_generator.rb +230 -138
  20. data/lib/generators/hot_glue/templates/_errors.haml +6 -5
  21. data/lib/generators/hot_glue/templates/_flash_notices.haml +7 -6
  22. data/lib/generators/hot_glue/templates/_new_form.haml +10 -0
  23. data/lib/generators/hot_glue/templates/_show.haml +1 -1
  24. data/lib/generators/hot_glue/templates/{base_controller.rb → base_controller.rb.erb} +0 -0
  25. data/lib/generators/hot_glue/templates/{controller.rb → controller.rb.erb} +11 -7
  26. data/lib/generators/hot_glue/templates/create.turbo_stream.haml +12 -3
  27. data/lib/generators/hot_glue/templates/edit.haml +2 -0
  28. data/lib/generators/hot_glue/templates/new.haml +1 -10
  29. data/lib/generators/hot_glue/templates/{controller_spec.rb → request_spec.rb.erb} +0 -0
  30. data/lib/generators/hot_glue/templates/system_spec.rb.erb +53 -0
  31. data/lib/hotglue/version.rb +1 -1
  32. metadata +24 -13
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
17
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
20
  load 'rails/tasks/statistics.rake'
File without changes
data/bin/rails CHANGED
@@ -3,8 +3,8 @@
3
3
  # installed from the root of your application.
4
4
 
5
5
  ENGINE_ROOT = File.expand_path('..', __dir__)
6
- ENGINE_PATH = File.expand_path('../lib/common_core_js/engine', __dir__)
7
- APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
6
+ ENGINE_PATH = File.expand_path('../lib/hotglue/engine', __dir__)
7
+ APP_PATH = File.expand_path('../spec/dummy/application', __dir__)
8
8
 
9
9
  # Set up gems listed in the Gemfile.
10
10
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
@@ -0,0 +1,11 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: ../spec/dummy/db/development.sqlite3
4
+ pool: 5
5
+ timeout: 5000
6
+
7
+ test:
8
+ adapter: sqlite3
9
+ database: ../spec/dummy/db/test.sqlite3
10
+ pool: 5
11
+ timeout: 5000
@@ -0,0 +1,11 @@
1
+ class CreateAbcs < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :abcs do |t|
4
+ t.integer :xxx
5
+ t.string :yyy
6
+ t.integer :def_id
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class CreateDefs < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :defs do |t|
4
+ t.integer :user_id
5
+ t.string :name
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
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
@@ -0,0 +1,9 @@
1
+ class CreateJkls < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :jkls do |t|
4
+ t.integer :hgi_id
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DeviseCreateUsers < ActiveRecord::Migration[6.1]
4
+ def change
5
+ create_table :users do |t|
6
+ ## Database authenticatable
7
+ t.string :email, null: false, default: ""
8
+ t.string :encrypted_password, null: false, default: ""
9
+
10
+ ## Recoverable
11
+ t.string :reset_password_token
12
+ t.datetime :reset_password_sent_at
13
+
14
+ ## Rememberable
15
+ t.datetime :remember_created_at
16
+
17
+ ## Trackable
18
+ # t.integer :sign_in_count, default: 0, null: false
19
+ # t.datetime :current_sign_in_at
20
+ # t.datetime :last_sign_in_at
21
+ # t.string :current_sign_in_ip
22
+ # t.string :last_sign_in_ip
23
+
24
+ ## Confirmable
25
+ # t.string :confirmation_token
26
+ # t.datetime :confirmed_at
27
+ # t.datetime :confirmation_sent_at
28
+ # t.string :unconfirmed_email # Only if using reconfirmable
29
+
30
+ ## Lockable
31
+ # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
32
+ # t.string :unlock_token # Only if unlock strategy is :email or :both
33
+ # t.datetime :locked_at
34
+
35
+
36
+ t.timestamps null: false
37
+ end
38
+
39
+ add_index :users, :email, unique: true
40
+ add_index :users, :reset_password_token, unique: true
41
+ # add_index :users, :confirmation_token, unique: true
42
+ # add_index :users, :unlock_token, unique: true
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ class CreateXyzs < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :xyzs do |t|
4
+ t.integer :nothing_id
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
data/db/schema.rb ADDED
@@ -0,0 +1,60 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # This file is the source Rails uses to define your schema when running `bin/rails
6
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
+ # be faster and is potentially less error prone than running all of your
8
+ # migrations from scratch. Old migrations may fail to apply correctly if those
9
+ # migrations use external dependencies or application code.
10
+ #
11
+ # It's strongly recommended that you check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(version: 2021_03_06_225506) do
14
+
15
+ create_table "abcs", force: :cascade do |t|
16
+ t.integer "xxx"
17
+ t.string "yyy"
18
+ t.integer "def_id"
19
+ t.datetime "created_at", precision: 6, null: false
20
+ t.datetime "updated_at", precision: 6, null: false
21
+ end
22
+
23
+ create_table "defs", force: :cascade do |t|
24
+ t.integer "user_id"
25
+ t.string "name"
26
+ t.datetime "created_at", precision: 6, null: false
27
+ t.datetime "updated_at", precision: 6, null: false
28
+ end
29
+
30
+ create_table "hgis", force: :cascade do |t|
31
+ t.integer "def_id"
32
+ t.datetime "created_at", precision: 6, null: false
33
+ t.datetime "updated_at", precision: 6, null: false
34
+ end
35
+
36
+ create_table "jkls", force: :cascade do |t|
37
+ t.integer "hgi_id"
38
+ t.datetime "created_at", precision: 6, null: false
39
+ t.datetime "updated_at", precision: 6, null: false
40
+ end
41
+
42
+ create_table "users", force: :cascade do |t|
43
+ t.string "email", default: "", null: false
44
+ t.string "encrypted_password", default: "", null: false
45
+ t.string "reset_password_token"
46
+ t.datetime "reset_password_sent_at"
47
+ t.datetime "remember_created_at"
48
+ t.datetime "created_at", precision: 6, null: false
49
+ t.datetime "updated_at", precision: 6, null: false
50
+ t.index ["email"], name: "index_users_on_email", unique: true
51
+ t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
52
+ end
53
+
54
+ create_table "xyzs", force: :cascade do |t|
55
+ t.integer "nothing_id"
56
+ t.datetime "created_at", precision: 6, null: false
57
+ t.datetime "updated_at", precision: 6, null: false
58
+ end
59
+
60
+ end
@@ -10,9 +10,9 @@ module HotGlue
10
10
 
11
11
  def initialize(*args) #:nodoc:
12
12
  super
13
- # copy_file "common_core.js", "app/javascript/common_core.js"
14
- # copy_file "common_core.scss", "app/assets/stylesheets/common_core.scss"
15
- copy_file "_flash_notices.haml", "app/views/layouts/_flash_notices.haml"
13
+ # copy_file "hot_glue.js", "#{'spec/dummy/' if Rails.env.test?}app/javascript/hot_glue.js"
14
+ # copy_file "hot_glue.scss", "#{'spec/dummy/' if Rails.env.test?}app/assets/stylesheets/hot_glue.scss"
15
+ copy_file "_flash_notices.haml", "#{'spec/dummy/' if Rails.env.test?}app/views/layouts/_flash_notices.haml"
16
16
  end
17
17
  end
18
18
  end
@@ -3,6 +3,12 @@ require 'ffaker'
3
3
 
4
4
 
5
5
  module HotGlue
6
+
7
+
8
+ class Error < StandardError
9
+ end
10
+
11
+
6
12
  module GeneratorHelper
7
13
  def text_area_output(col, field_length, col_identifier )
8
14
  lines = field_length % 40
@@ -38,153 +44,191 @@ module HotGlue
38
44
  include GeneratorHelper
39
45
 
40
46
 
41
- def initialize(*meta_args) #:nodoc:
42
- super
47
+ class_option :singular, type: :string, default: nil
48
+ class_option :plural, type: :string, default: nil
49
+ class_option :singular_class, type: :string, default: nil
50
+ class_option :nest, type: :string, default: ""
51
+ class_option :namespace, type: :string, default: nil
52
+ class_option :auth, type: :string, default: nil
53
+ class_option :auth_identifier, type: :string, default: nil
54
+ class_option :exclude, type: :string, default: ""
55
+ class_option :include, type: :string, default: ""
56
+ class_option :god, type: :boolean, default: false
57
+ class_option :gd, type: :boolean, default: false # alias for god
58
+ class_option :specs_only, type: :boolean, default: false
59
+ class_option :no_specs, type: :boolean, default: false
60
+ class_option :no_delete, type: :boolean, default: false
61
+ class_option :no_create, type: :boolean, default: false
62
+ class_option :no_paginate, type: :boolean, default: false
63
+ class_option :big_edit, type: :boolean, default: false
64
+ class_option :show_only, type: :string, default: ""
43
65
 
44
- begin
45
- object = eval(class_name)
46
- rescue StandardError => e
47
- puts "*** Oops: It looks like there is no object for #{class_name}. Please define the object + database table first."
48
- exit
49
- end
66
+ def initialize(*meta_args) #:nodoc:
67
+ super
50
68
 
69
+ begin
70
+ object = eval(class_name)
71
+ rescue StandardError => e
72
+ message = "*** Oops: It looks like there is no object for #{class_name}. Please define the object + database table first."
73
+ raise(HotGlue::Error, message)
74
+ end
51
75
 
76
+ if @specs_only && @no_specs
77
+ raise(HotGlue::Error, "*** Oops: You seem to have specified both the --specs-only flag and --no-specs flags. this doesn't make any sense, so I am aborting. sorry.")
78
+ end
52
79
 
53
- args = meta_args[0]
54
- @singular = args[0].tableize.singularize # should be in form hello_world
55
80
 
81
+ args = meta_args[0]
82
+ @singular = args.first.tableize.singularize # should be in form hello_world
83
+ @plural = options['plural'] || @singular + "s" # supply to override; leave blank to use default
84
+ @auth = options['auth'] || "current_user"
85
+ @auth_identifier = options['auth'] || (!@auth.nil? && @auth.gsub("current_", "")) || nil
86
+ @nest = options['auth'] || nil
87
+ @namespace = options['namespace'] || nil
88
+ @singular_class = @singular.titleize.gsub(" ", "")
89
+ @exclude_fields = []
90
+ @exclude_fields += options['exclude'].split(",").collect(&:to_sym)
91
+
92
+ if !options['include'].empty?
93
+ @include_fields = []
94
+ @include_fields += options['include'].split(",").collect(&:to_sym)
95
+ end
56
96
 
57
- @plural = @singular + "s" # supply to override; leave blank to use default
58
- @singular_class = @singular.titleize.gsub(" ", "")
59
- @nest = nil
60
- @namespace = nil
61
- @nested_args = []
62
97
 
63
- @auth = "current_user"
64
- @auth_identifier = nil
65
- @exclude_fields = []
98
+ @show_only = []
99
+ if !options['show_only'].empty?
100
+ @show_only += options['show_only'].split(",").collect(&:to_sym)
101
+ end
66
102
 
67
- args[1..-1].each do |a|
68
- var_name, var_value = a.split("=")
69
- case (var_name)
103
+ auth_assoc = @auth.gsub("current_","")
70
104
 
71
- when "plural"
72
- @plural = var_value
73
- when "nest"
74
- @nest = var_value
75
- when "namespace"
76
- @namespace = var_value
77
- when "auth"
78
- @auth = var_value
79
- when "auth_identifier"
80
- @auth_identifier = var_value || ""
81
- when "exclude"
82
- @exclude_fields += var_value.split(",").collect(&:to_sym)
83
- end
84
- end
105
+ @god = options['god'] || options['gd'] || false
106
+ @specs_only = options['specs_only'] || false
85
107
 
86
- auth_assoc = @auth.gsub("current_","")
108
+ @no_specs = options['no_specs'] || false
109
+ @no_delete = options['no_delete'] || false
87
110
 
88
- @no_delete = false
89
- @no_create = false
111
+ @no_create = options['no_create'] || false
112
+ @no_paginate = options['no_paginate'] || false
113
+ @big_edit = options['big_edit']
90
114
 
91
- flags = meta_args[1]
92
- flags.each do |f|
93
- case (f)
94
- when "--god"
115
+ if @god
95
116
  @auth = nil
96
- when "--specs-only"
97
- @specs_only = true
98
- when "--no-specs"
99
- @no_specs = true
100
- when "--no-delete"
101
- @no_delete = true
102
- when "--no-create"
103
- @no_create = true
104
- when "--no-paginate"
105
- @no_paginate = true
106
117
  end
107
- end
108
118
 
109
- if @specs_only && @no_specs
110
- puts "*** Oops: You seem to have specified both the --specs-only flag and --no-specs flags. this doesn't make any sense, so I am aborting. sorry."
111
- exit
112
- end
119
+ # when in self auth, the object is the same as the authenticated object
120
+ if @auth && auth_identifier == @singular
121
+ @self_auth = true
122
+ end
113
123
 
124
+ @nested_args = []
125
+ if !@nest.nil?
126
+ @nested_args = @nest.split("/")
127
+ @nested_args_plural = {}
128
+ @nested_args.each do |a|
129
+ @nested_args_plural[a] = a + "s"
130
+ end
131
+ end
114
132
 
115
- # only used for the before_action
116
- if @auth_identifier.nil? && !@auth.nil?
117
- @auth_identifier = @auth.gsub("current_", "")
118
- end
133
+ # the @object_owner will always be object that will 'own' the object
134
+ # for new and create
119
135
 
120
- # when in self auth, the object is the same as the authenticated object
121
- if @auth && auth_identifier == @singular
122
- @self_auth = true
123
- end
136
+ if @auth && ! @self_auth && @nested_args.none?
137
+ @object_owner_sym = @auth.gsub("current_", "").to_sym
138
+ @object_owner_eval = @auth
139
+ else
124
140
 
125
- if !@nest.nil?
126
- @nested_args = @nest.split("/")
127
- @nested_args_plural = {}
128
- @nested_args.each do |a|
129
- @nested_args_plural[a] = a + "s"
141
+ if @nested_args.any?
142
+ @object_owner_sym = @nested_args.last.to_sym
143
+ @object_owner_eval = "@#{@nested_args.last}"
144
+ else
145
+ @object_owner_sym = ""
146
+ @object_owner_eval = ""
147
+ end
130
148
  end
131
- end
132
149
 
133
- # the @object_owner will always be object that will 'own' the object
134
- # for new and create
135
150
 
136
- if @auth && ! @self_auth && @nested_args.none?
137
- @object_owner_sym = @auth.gsub("current_", "").to_sym
138
- @object_owner_eval = @auth
139
- else
151
+ if !@object_owner_sym.empty?
152
+ auth_assoc_field = auth_assoc + "_id"
153
+ assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
140
154
 
141
- if @nested_args.any?
142
- @object_owner_sym = @nested_args.last.to_sym
143
- @object_owner_eval = "@#{@nested_args.last}"
144
- else
145
- @object_owner_sym = ""
146
- @object_owner_eval = ""
155
+ if assoc
156
+ ownership_field = assoc.name.to_s + "_id"
157
+ else
158
+ # if @auth
159
+ 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."
160
+ # else
161
+ # exit_message= "*** Oops: god mode could not find the association(?). something is wrong."
162
+ # end
163
+ raise(HotGlue::Error, exit_message)
164
+ end
147
165
  end
148
- end
149
166
 
167
+ if !@include_fields
168
+ @exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
169
+ :reset_password_token,
170
+ :reset_password_sent_at, :remember_created_at,
171
+ :confirmation_token, :confirmed_at,
172
+ :confirmation_sent_at, :unconfirmed_email
173
+
174
+ @exclude_fields.push(auth_assoc_field.to_sym) if !auth_assoc_field.nil?
175
+ @exclude_fields.push(ownership_field.to_sym) if !ownership_field.nil?
150
176
 
151
177
 
152
- # create the columns
153
- if !@object_owner_sym.empty?
154
- auth_assoc_field = auth_assoc + "_id"
155
- assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
156
- if assoc
157
- ownership_field = assoc.name.to_s + "_id"
178
+ @columns = object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
179
+
158
180
  else
159
- if @auth
160
- puts "*** 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."
161
- else
162
- puts "*** Oops: god mode could not find the association(?). something is wrong."
163
- end
164
- exit
181
+ @columns = object.columns.map(&:name).map(&:to_sym).reject{|field| !@include_fields.include?(field) }
182
+
165
183
  end
166
- end
167
184
 
168
- @exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
169
- :reset_password_token,
170
- :reset_password_sent_at, :remember_created_at,
171
- :confirmation_token, :confirmed_at,
172
- :confirmation_sent_at, :unconfirmed_email
185
+ @columns.each do |col|
186
+ if col.to_s.starts_with?("_")
187
+ @show_only << col
188
+ end
173
189
 
174
- @exclude_fields += auth_assoc_field.to_sym if !auth_assoc_field.nil?
175
- @exclude_fields += ownership_field.to_sym if !ownership_field.nil?
190
+ if object.columns_hash[col.to_s].type == :integer
191
+ if col.to_s.ends_with?("_id")
192
+ # guess the association name label
193
+ assoc_name = col.to_s.gsub("_id","")
194
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
176
195
 
177
- begin
178
- @columns = object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
179
- rescue StandardError => e
180
- puts "Ooops... #{e} it looks like is no object for #{class_name}. Please create the database table with fields first. "
181
- exit
182
- end
183
196
 
197
+ begin
198
+ eval(assoc.class_name)
199
+ rescue NameError => e
200
+ 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} "
201
+ raise(HotGlue::Error, exit_message)
184
202
 
203
+ end
185
204
 
205
+
206
+ if assoc.nil?
207
+ exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
208
+ raise(HotGlue::Error,exit_message)
209
+ end
210
+
211
+ assoc_class = eval(assoc.class_name)
212
+
213
+ name_list = [:name, :to_label, :full_name, :display_name, :email]
214
+
215
+
216
+ if name_list.collect{ |field|
217
+ assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
218
+ }.any?
219
+ # do nothing here
220
+ else
221
+ 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)"
222
+ raise(HotGlue::Error,exit_message)
223
+ end
224
+ end
225
+ end
226
+ end
186
227
  end
187
228
 
229
+
230
+
231
+ #
188
232
  def formats
189
233
  [format]
190
234
  end
@@ -197,17 +241,19 @@ module HotGlue
197
241
  @default_colspan = @columns.size
198
242
 
199
243
  unless @specs_only
200
- template "controller.rb", File.join("app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
244
+ template "controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
201
245
  if @namespace && defined?(controller_descends_from) == nil
202
- template "base_controller.rb", File.join("app/controllers#{namespace_with_dash}", "base_controller.rb")
246
+ template "base_controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "base_controller.rb")
203
247
  end
204
248
  end
205
249
 
206
250
  unless @no_specs
207
- template "controller_spec.rb", File.join("spec/controllers#{namespace_with_dash}", "#{plural}_controller_spec.rb")
251
+ template "request_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/request#{namespace_with_dash}", "#{plural}_spec.rb")
252
+ template "system_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_spec.rb")
253
+
208
254
  end
209
255
 
210
- template "_errors.haml", File.join("app/views#{namespace_with_dash}", "_errors.haml")
256
+ template "_errors.haml", File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", "_errors.haml")
211
257
  end
212
258
 
213
259
  def list_column_headings
@@ -402,14 +448,14 @@ module HotGlue
402
448
  haml_views.each do |view|
403
449
  formats.each do |format|
404
450
  filename = cc_filename_with_extensions(view, "haml")
405
- template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
451
+ template filename, File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", controller_file_path, filename)
406
452
  end
407
453
  end
408
454
 
409
455
  turbo_stream_views.each do |view|
410
456
  formats.each do |format|
411
457
  filename = cc_filename_with_extensions(view, 'turbo_stream.haml')
412
- template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
458
+ template filename, File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", controller_file_path, filename)
413
459
  end
414
460
  end
415
461
  end
@@ -431,13 +477,21 @@ module HotGlue
431
477
  end
432
478
 
433
479
  def haml_views
434
- res = %w(index edit new _form _line _list _new_button _show)
480
+ res = %w(index edit _form _line _list _show _errors)
481
+
482
+ unless @no_create
483
+ res += %w(new _new_form _new_button)
484
+ end
435
485
 
436
486
  res
437
487
  end
438
488
 
439
489
  def turbo_stream_views
440
- res = %w(create destroy edit update)
490
+ res = %w(create edit update)
491
+ unless @no_delete
492
+ res << 'destroy'
493
+ end
494
+ res
441
495
  end
442
496
 
443
497
  def handler
@@ -458,6 +512,16 @@ module HotGlue
458
512
  col_spaces_prepend = " "
459
513
 
460
514
  res = @columns.map { |col|
515
+
516
+ if @show_only.include?(col)
517
+
518
+ "#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
519
+ = @#{singular}.#{col.to_s}
520
+ %label.form-text
521
+ #{col.to_s.humanize}\n"
522
+ else
523
+
524
+
461
525
  type = eval("#{singular_class}.columns_hash['#{col}']").type
462
526
  limit = eval("#{singular_class}.columns_hash['#{col}']").limit
463
527
  sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
@@ -466,31 +530,29 @@ module HotGlue
466
530
  when :integer
467
531
  # look for a belongs_to on this object
468
532
  if col.to_s.ends_with?("_id")
469
- # guess the association name label
470
-
471
-
472
533
  assoc_name = col.to_s.gsub("_id","")
473
534
  assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
474
535
  if assoc.nil?
475
- puts "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
536
+ exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
476
537
  exit
477
538
  end
478
539
 
479
540
 
480
541
  assoc_class = eval(assoc.class_name)
481
542
 
482
- if assoc_class.column_names.include?("name")
543
+ if assoc_class.respond_to?("name")
483
544
  display_column = "name"
484
- elsif assoc_class.column_names.include?("to_label")
545
+ elsif assoc_class.respond_to?("to_label")
485
546
  display_column = "to_label"
486
- elsif assoc_class.column_names.include?("full_name")
547
+ elsif assoc_class.respond_to?("full_name")
487
548
  display_column = "full_name"
488
- elsif assoc_class.column_names.include?("display_name")
549
+ elsif assoc_class.respond_to?("display_name")
489
550
  display_column = "display_name"
490
- elsif assoc_class.column_names.include?("email")
551
+ elsif assoc_class.respond_to?("email")
491
552
  display_column = "email"
492
553
  else
493
- 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)"
554
+ raise("this should have been caught by the checker in the initializer")
555
+ # 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)"
494
556
  end
495
557
 
496
558
  "#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{assoc_name.to_s})}\"}
@@ -544,7 +606,7 @@ module HotGlue
544
606
  #{col_spaces_prepend}= f.label(:#{col.to_s}, value: 'Yes', for: '#{singular}_#{col.to_s}_1')
545
607
  "
546
608
  end
547
-
609
+ end
548
610
  }.join("\n")
549
611
  return res
550
612
  end
@@ -571,24 +633,27 @@ module HotGlue
571
633
  assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
572
634
 
573
635
  if assoc.nil?
574
- puts "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
575
- exit
636
+ exit_message = "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
637
+ raise(HotGlue::Error,exit_message)
576
638
  end
577
639
 
578
640
  assoc_class = eval(assoc.class_name)
579
641
 
580
- if assoc_class.column_names.include?("name")
642
+ if assoc_class.respond_to?("name")
581
643
  display_column = "name"
582
- elsif assoc_class.column_names.include?("to_label")
644
+ elsif assoc_class.respond_to?("to_label")
583
645
  display_column = "to_label"
584
- elsif assoc_class.column_names.include?("full_name")
646
+ elsif assoc_class.respond_to?("full_name")
585
647
  display_column = "full_name"
586
- elsif assoc_class.column_names.include?("display_name")
648
+ elsif assoc_class.respond_to?("display_name")
587
649
  display_column = "display_name"
588
- elsif assoc_class.column_names.include?("email")
650
+ elsif assoc_class.respond_to?("email")
589
651
  display_column = "email"
652
+ elsif assoc_class.respond_to?("number")
653
+ display_column = "number"
654
+
590
655
  else
591
- 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)"
656
+ 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)"
592
657
  end
593
658
 
594
659
  "#{col_identifer}
@@ -658,6 +723,32 @@ module HotGlue
658
723
  end
659
724
 
660
725
 
726
+
727
+ def display_class
728
+ me = eval(singular_class)
729
+
730
+ @display_class ||=
731
+ if me.column_names.include?("name")
732
+ # note that all class object respond_to?(:name) with the name of their own class
733
+ # this one is unique
734
+ "name"
735
+ elsif me.column_names.include?("to_label") || me.instance_methods(false).include?(:to_label)
736
+ "to_label"
737
+ elsif me.column_names.include?("full_name") || me.instance_methods(false).include?(:full_name)
738
+ "full_name"
739
+ elsif me.column_names.include?("display_name") || me.instance_methods(false).include?(:display_name)
740
+ "display_name"
741
+ elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
742
+ "email"
743
+ elsif me.column_names.include?("number") || me.instance_methods(false).include?(:number)
744
+ "number"
745
+
746
+ else
747
+ 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)"
748
+ raise(HotGlue::Error, exit_message)
749
+ end
750
+ end
751
+
661
752
  def destroy_action
662
753
  return false if @self_auth
663
754
  return !@no_delete
@@ -679,7 +770,8 @@ module HotGlue
679
770
 
680
771
 
681
772
  def paginate
682
- "= paginate #{plural}"
773
+ "- if #{plural}.respond_to?(:total_pages)
774
+ = paginate #{plural}"
683
775
  end
684
776
 
685
777
  private # thor does something fancy like sending the class all of its own methods during some strange run sequence