hot-glue 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -1
- data/.gitignore +12 -7
- data/Gemfile +4 -9
- data/Gemfile.lock +78 -57
- data/README.md +120 -28
- data/Rakefile +1 -1
- data/app/assets/config/manifest.js +0 -0
- data/bin/rails +2 -2
- data/config/database.yml +11 -0
- data/db/migrate/20210306212711_create_abcs.rb +11 -0
- data/db/migrate/20210306223300_create_defs.rb +9 -0
- data/db/migrate/20210306223305_create_ghis.rb +9 -0
- data/db/migrate/20210306223309_create_jkls.rb +9 -0
- data/db/migrate/20210306223701_devise_create_users.rb +44 -0
- data/db/migrate/20210306225506_create_xyzs.rb +9 -0
- data/db/schema.rb +60 -0
- data/lib/generators/hot_glue/install_generator.rb +3 -3
- data/lib/generators/hot_glue/scaffold_generator.rb +193 -100
- data/lib/generators/hot_glue/templates/_new_form.haml +0 -3
- data/lib/generators/hot_glue/templates/_show.haml +2 -2
- data/lib/generators/hot_glue/templates/{base_controller.rb → base_controller.rb.erb} +0 -0
- data/lib/generators/hot_glue/templates/{controller.rb → controller.rb.erb} +13 -10
- data/lib/generators/hot_glue/templates/edit.haml +2 -0
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +148 -0
- data/lib/generators/hot_glue/templates/update.turbo_stream.haml +4 -0
- data/lib/hotglue/version.rb +1 -1
- metadata +21 -12
- data/lib/generators/hot_glue/templates/controller_spec.rb +0 -110
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("
|
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/
|
7
|
-
APP_PATH = File.expand_path('../
|
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__)
|
data/config/database.yml
ADDED
@@ -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
|
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 "ghis", 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 "
|
14
|
-
# copy_file "
|
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,7 +3,35 @@ require 'ffaker'
|
|
3
3
|
|
4
4
|
|
5
5
|
module HotGlue
|
6
|
+
class Error < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
6
13
|
module GeneratorHelper
|
14
|
+
def derrive_reference_name thing_as_string
|
15
|
+
assoc_class = eval(thing_as_string)
|
16
|
+
|
17
|
+
if assoc_class.respond_to?("name")
|
18
|
+
display_column = "name"
|
19
|
+
elsif assoc_class.respond_to?("to_label")
|
20
|
+
display_column = "to_label"
|
21
|
+
elsif assoc_class.respond_to?("full_name")
|
22
|
+
display_column = "full_name"
|
23
|
+
elsif assoc_class.respond_to?("display_name")
|
24
|
+
display_column = "display_name"
|
25
|
+
elsif assoc_class.respond_to?("email")
|
26
|
+
display_column = "email"
|
27
|
+
else
|
28
|
+
raise("this should have been caught by the checker in the initializer")
|
29
|
+
# 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)"
|
30
|
+
end
|
31
|
+
display_column
|
32
|
+
end
|
33
|
+
|
34
|
+
|
7
35
|
def text_area_output(col, field_length, col_identifier )
|
8
36
|
lines = field_length % 40
|
9
37
|
if lines > 5
|
@@ -46,12 +74,16 @@ module HotGlue
|
|
46
74
|
class_option :auth, type: :string, default: nil
|
47
75
|
class_option :auth_identifier, type: :string, default: nil
|
48
76
|
class_option :exclude, type: :string, default: ""
|
77
|
+
class_option :include, type: :string, default: ""
|
49
78
|
class_option :god, type: :boolean, default: false
|
50
|
-
class_option :
|
79
|
+
class_option :gd, type: :boolean, default: false # alias for god
|
80
|
+
class_option :specs_only, type: :boolean, default: false
|
51
81
|
class_option :no_specs, type: :boolean, default: false
|
52
82
|
class_option :no_delete, type: :boolean, default: false
|
53
83
|
class_option :no_create, type: :boolean, default: false
|
54
84
|
class_option :no_paginate, type: :boolean, default: false
|
85
|
+
class_option :big_edit, type: :boolean, default: false
|
86
|
+
class_option :show_only, type: :string, default: ""
|
55
87
|
|
56
88
|
def initialize(*meta_args) #:nodoc:
|
57
89
|
super
|
@@ -59,55 +91,61 @@ module HotGlue
|
|
59
91
|
begin
|
60
92
|
object = eval(class_name)
|
61
93
|
rescue StandardError => e
|
62
|
-
|
63
|
-
|
94
|
+
message = "*** Oops: It looks like there is no object for #{class_name}. Please define the object + database table first."
|
95
|
+
raise(HotGlue::Error, message)
|
96
|
+
end
|
97
|
+
|
98
|
+
if @specs_only && @no_specs
|
99
|
+
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.")
|
64
100
|
end
|
65
|
-
args = meta_args[0]
|
66
|
-
@singular = args.first.tableize.singularize # should be in form hello_world
|
67
101
|
|
68
102
|
|
103
|
+
args = meta_args[0]
|
104
|
+
@singular = args.first.tableize.singularize # should be in form hello_world
|
69
105
|
@plural = options['plural'] || @singular + "s" # supply to override; leave blank to use default
|
70
106
|
@auth = options['auth'] || "current_user"
|
71
|
-
@auth_identifier = options['
|
107
|
+
@auth_identifier = options['auth_identifier'] || (!@auth.nil? && @auth.gsub("current_", "")) || nil
|
72
108
|
|
73
109
|
|
74
|
-
@nest = options['
|
110
|
+
@nest = (!options['nest'].empty? && options['nest']) || nil
|
75
111
|
@namespace = options['namespace'] || nil
|
76
112
|
|
77
113
|
@singular_class = @singular.titleize.gsub(" ", "")
|
78
|
-
|
79
114
|
@exclude_fields = []
|
115
|
+
@exclude_fields += options['exclude'].split(",").collect(&:to_sym)
|
80
116
|
|
117
|
+
if !options['include'].empty?
|
118
|
+
@include_fields = []
|
119
|
+
@include_fields += options['include'].split(",").collect(&:to_sym)
|
120
|
+
end
|
81
121
|
|
82
122
|
|
83
|
-
@
|
123
|
+
@show_only = []
|
124
|
+
if !options['show_only'].empty?
|
125
|
+
@show_only += options['show_only'].split(",").collect(&:to_sym)
|
126
|
+
end
|
84
127
|
|
85
128
|
auth_assoc = @auth.gsub("current_","")
|
86
129
|
|
87
|
-
|
88
130
|
@god = options['god'] || options['gd'] || false
|
89
|
-
@specs_only = options['
|
90
|
-
@no_specs = options['no-specs'] || false
|
91
|
-
@no_delete = options['no-delete'] || false
|
92
|
-
@no_create = options['no-create'] || false
|
93
|
-
@no_paginate = options['no-paginate'] || false
|
131
|
+
@specs_only = options['specs_only'] || false
|
94
132
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
133
|
+
@no_specs = options['no_specs'] || false
|
134
|
+
@no_delete = options['no_delete'] || false
|
135
|
+
|
136
|
+
@no_create = options['no_create'] || false
|
137
|
+
@no_paginate = options['no_paginate'] || false
|
138
|
+
@big_edit = options['big_edit']
|
99
139
|
|
100
140
|
if @god
|
101
141
|
@auth = nil
|
102
142
|
end
|
103
143
|
|
104
|
-
|
105
144
|
# when in self auth, the object is the same as the authenticated object
|
106
145
|
if @auth && auth_identifier == @singular
|
107
146
|
@self_auth = true
|
108
147
|
end
|
109
148
|
|
110
|
-
|
111
149
|
@nested_args = []
|
112
150
|
if !@nest.nil?
|
113
151
|
@nested_args = @nest.split("/")
|
@@ -134,42 +172,101 @@ module HotGlue
|
|
134
172
|
end
|
135
173
|
end
|
136
174
|
|
137
|
-
|
175
|
+
|
138
176
|
if !@object_owner_sym.empty?
|
139
177
|
auth_assoc_field = auth_assoc + "_id"
|
140
178
|
assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
|
179
|
+
|
141
180
|
if assoc
|
142
181
|
ownership_field = assoc.name.to_s + "_id"
|
182
|
+
elsif !@nest
|
183
|
+
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."
|
184
|
+
|
143
185
|
else
|
144
|
-
if @
|
145
|
-
|
186
|
+
if @god
|
187
|
+
|
188
|
+
exit_message= "*** Oops: god mode could not find the association(?). something is wrong."
|
146
189
|
else
|
147
|
-
|
190
|
+
@auth_check = "current_user"
|
191
|
+
@nested_args.each do |arg|
|
192
|
+
|
193
|
+
if !@auth_check.method("#{arg}s")
|
194
|
+
exit_message= "*** Oops: your nesting chain does not have a assocation for #{arg}s on #{@auth_check} something is wrong."
|
195
|
+
end
|
196
|
+
byebug
|
197
|
+
puts ""
|
198
|
+
end
|
148
199
|
end
|
149
|
-
|
200
|
+
|
201
|
+
raise(HotGlue::Error, exit_message)
|
150
202
|
end
|
151
203
|
end
|
152
204
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
205
|
+
if !@include_fields
|
206
|
+
@exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
|
207
|
+
:reset_password_token,
|
208
|
+
:reset_password_sent_at, :remember_created_at,
|
209
|
+
:confirmation_token, :confirmed_at,
|
210
|
+
:confirmation_sent_at, :unconfirmed_email
|
211
|
+
|
212
|
+
@exclude_fields.push(auth_assoc_field.to_sym) if !auth_assoc_field.nil?
|
213
|
+
@exclude_fields.push(ownership_field.to_sym) if !ownership_field.nil?
|
158
214
|
|
159
|
-
@exclude_fields.push(auth_assoc_field.to_sym) if !auth_assoc_field.nil?
|
160
|
-
@exclude_fields.push(ownership_field.to_sym) if !ownership_field.nil?
|
161
215
|
|
162
|
-
begin
|
163
216
|
@columns = object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
|
164
|
-
|
165
|
-
|
166
|
-
|
217
|
+
|
218
|
+
else
|
219
|
+
@columns = object.columns.map(&:name).map(&:to_sym).reject{|field| !@include_fields.include?(field) }
|
220
|
+
|
167
221
|
end
|
168
222
|
|
223
|
+
@columns.each do |col|
|
224
|
+
if col.to_s.starts_with?("_")
|
225
|
+
@show_only << col
|
226
|
+
end
|
227
|
+
|
228
|
+
if object.columns_hash[col.to_s].type == :integer
|
229
|
+
if col.to_s.ends_with?("_id")
|
230
|
+
# guess the association name label
|
231
|
+
assoc_name = col.to_s.gsub("_id","")
|
232
|
+
assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
233
|
+
|
234
|
+
|
235
|
+
begin
|
236
|
+
eval(assoc.class_name)
|
237
|
+
rescue NameError => e
|
238
|
+
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."
|
239
|
+
raise(HotGlue::Error, exit_message)
|
169
240
|
|
241
|
+
end
|
170
242
|
|
243
|
+
|
244
|
+
if assoc.nil?
|
245
|
+
exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
246
|
+
raise(HotGlue::Error,exit_message)
|
247
|
+
end
|
248
|
+
|
249
|
+
assoc_class = eval(assoc.class_name)
|
250
|
+
|
251
|
+
name_list = [:name, :to_label, :full_name, :display_name, :email]
|
252
|
+
|
253
|
+
|
254
|
+
if name_list.collect{ |field|
|
255
|
+
assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
|
256
|
+
}.any?
|
257
|
+
# do nothing here
|
258
|
+
else
|
259
|
+
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)"
|
260
|
+
raise(HotGlue::Error,exit_message)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
171
265
|
end
|
172
266
|
|
267
|
+
|
268
|
+
|
269
|
+
#
|
173
270
|
def formats
|
174
271
|
[format]
|
175
272
|
end
|
@@ -182,17 +279,22 @@ module HotGlue
|
|
182
279
|
@default_colspan = @columns.size
|
183
280
|
|
184
281
|
unless @specs_only
|
185
|
-
template "controller.rb", File.join("app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
|
186
|
-
if @namespace
|
187
|
-
|
282
|
+
template "controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
|
283
|
+
if @namespace
|
284
|
+
begin
|
285
|
+
eval(controller_descends_from)
|
286
|
+
puts " skipping base controller #{controller_descends_from}"
|
287
|
+
rescue NameError => e
|
288
|
+
template "base_controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "base_controller.rb")
|
289
|
+
end
|
188
290
|
end
|
189
291
|
end
|
190
292
|
|
191
293
|
unless @no_specs
|
192
|
-
template "
|
294
|
+
template "system_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
|
193
295
|
end
|
194
296
|
|
195
|
-
template "_errors.haml", File.join("app/views#{namespace_with_dash}", "_errors.haml")
|
297
|
+
template "_errors.haml", File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", "_errors.haml")
|
196
298
|
end
|
197
299
|
|
198
300
|
def list_column_headings
|
@@ -268,9 +370,9 @@ module HotGlue
|
|
268
370
|
end
|
269
371
|
|
270
372
|
|
271
|
-
def path_helper_full
|
272
|
-
|
273
|
-
end
|
373
|
+
# def path_helper_full
|
374
|
+
# "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{singular}_path"
|
375
|
+
# end
|
274
376
|
|
275
377
|
def path_helper_args
|
276
378
|
if @nested_args.any?
|
@@ -382,19 +484,22 @@ module HotGlue
|
|
382
484
|
end
|
383
485
|
|
384
486
|
|
487
|
+
|
488
|
+
|
489
|
+
|
385
490
|
def copy_view_files
|
386
491
|
return if @specs_only
|
387
492
|
haml_views.each do |view|
|
388
493
|
formats.each do |format|
|
389
494
|
filename = cc_filename_with_extensions(view, "haml")
|
390
|
-
template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
|
495
|
+
template filename, File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", controller_file_path, filename)
|
391
496
|
end
|
392
497
|
end
|
393
498
|
|
394
499
|
turbo_stream_views.each do |view|
|
395
500
|
formats.each do |format|
|
396
501
|
filename = cc_filename_with_extensions(view, 'turbo_stream.haml')
|
397
|
-
template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
|
502
|
+
template filename, File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", controller_file_path, filename)
|
398
503
|
end
|
399
504
|
end
|
400
505
|
end
|
@@ -416,13 +521,21 @@ module HotGlue
|
|
416
521
|
end
|
417
522
|
|
418
523
|
def haml_views
|
419
|
-
res = %w(index edit
|
524
|
+
res = %w(index edit _form _line _list _show _errors)
|
525
|
+
|
526
|
+
unless @no_create
|
527
|
+
res += %w(new _new_form _new_button)
|
528
|
+
end
|
420
529
|
|
421
530
|
res
|
422
531
|
end
|
423
532
|
|
424
533
|
def turbo_stream_views
|
425
|
-
res = %w(create
|
534
|
+
res = %w(create edit update)
|
535
|
+
unless @no_delete
|
536
|
+
res << 'destroy'
|
537
|
+
end
|
538
|
+
res
|
426
539
|
end
|
427
540
|
|
428
541
|
def handler
|
@@ -443,6 +556,16 @@ module HotGlue
|
|
443
556
|
col_spaces_prepend = " "
|
444
557
|
|
445
558
|
res = @columns.map { |col|
|
559
|
+
|
560
|
+
if @show_only.include?(col)
|
561
|
+
|
562
|
+
"#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
|
563
|
+
= @#{singular}.#{col.to_s}
|
564
|
+
%label.form-text
|
565
|
+
#{col.to_s.humanize}\n"
|
566
|
+
else
|
567
|
+
|
568
|
+
|
446
569
|
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
447
570
|
limit = eval("#{singular_class}.columns_hash['#{col}']").limit
|
448
571
|
sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
|
@@ -451,35 +574,17 @@ module HotGlue
|
|
451
574
|
when :integer
|
452
575
|
# look for a belongs_to on this object
|
453
576
|
if col.to_s.ends_with?("_id")
|
454
|
-
# guess the association name label
|
455
|
-
|
456
|
-
|
457
577
|
assoc_name = col.to_s.gsub("_id","")
|
458
578
|
assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
459
579
|
if assoc.nil?
|
460
|
-
|
580
|
+
exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
461
581
|
exit
|
462
582
|
end
|
583
|
+
display_column = derrive_reference_name(assoc.class_name)
|
463
584
|
|
464
585
|
|
465
|
-
assoc_class = eval(assoc.class_name)
|
466
|
-
|
467
|
-
if assoc_class.column_names.include?("name")
|
468
|
-
display_column = "name"
|
469
|
-
elsif assoc_class.column_names.include?("to_label")
|
470
|
-
display_column = "to_label"
|
471
|
-
elsif assoc_class.column_names.include?("full_name")
|
472
|
-
display_column = "full_name"
|
473
|
-
elsif assoc_class.column_names.include?("display_name")
|
474
|
-
display_column = "display_name"
|
475
|
-
elsif assoc_class.column_names.include?("email")
|
476
|
-
display_column = "email"
|
477
|
-
else
|
478
|
-
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)"
|
479
|
-
end
|
480
|
-
|
481
586
|
"#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{assoc_name.to_s})}\"}
|
482
|
-
#{col_spaces_prepend}= f.collection_select(:#{col.to_s}, #{
|
587
|
+
#{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')
|
483
588
|
#{col_spaces_prepend}%label.small.form-text.text-muted
|
484
589
|
#{col_spaces_prepend} #{col.to_s.humanize}"
|
485
590
|
|
@@ -529,7 +634,7 @@ module HotGlue
|
|
529
634
|
#{col_spaces_prepend}= f.label(:#{col.to_s}, value: 'Yes', for: '#{singular}_#{col.to_s}_1')
|
530
635
|
"
|
531
636
|
end
|
532
|
-
|
637
|
+
end
|
533
638
|
}.join("\n")
|
534
639
|
return res
|
535
640
|
end
|
@@ -556,28 +661,12 @@ module HotGlue
|
|
556
661
|
assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
557
662
|
|
558
663
|
if assoc.nil?
|
559
|
-
|
560
|
-
|
664
|
+
exit_message = "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
665
|
+
raise(HotGlue::Error,exit_message)
|
561
666
|
end
|
562
|
-
|
563
|
-
assoc_class = eval(assoc.class_name)
|
564
667
|
|
565
|
-
|
566
|
-
display_column = "name"
|
567
|
-
elsif assoc_class.column_names.include?("to_label")
|
568
|
-
display_column = "to_label"
|
569
|
-
elsif assoc_class.column_names.include?("full_name")
|
570
|
-
display_column = "full_name"
|
571
|
-
elsif assoc_class.column_names.include?("display_name")
|
572
|
-
display_column = "display_name"
|
573
|
-
elsif assoc_class.column_names.include?("email")
|
574
|
-
display_column = "email"
|
575
|
-
elsif assoc_class.column_names.include?("number")
|
576
|
-
display_column = "number"
|
668
|
+
display_column = derrive_reference_name(assoc.class_name)
|
577
669
|
|
578
|
-
else
|
579
|
-
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)"
|
580
|
-
end
|
581
670
|
|
582
671
|
"#{col_identifer}
|
583
672
|
= #{singular}.#{assoc.name.to_s}.try(:#{display_column}) || '<span class=\"content alert-danger\">MISSING</span>'.html_safe"
|
@@ -649,22 +738,25 @@ module HotGlue
|
|
649
738
|
|
650
739
|
def display_class
|
651
740
|
me = eval(singular_class)
|
741
|
+
|
652
742
|
@display_class ||=
|
653
|
-
if me.column_names.include?("name")
|
743
|
+
if me.column_names.include?("name") || me.instance_methods(false).include?(:name)
|
744
|
+
# note that all class object respond_to?(:name) with the name of their own class
|
745
|
+
# this one is unique
|
654
746
|
"name"
|
655
|
-
elsif me.column_names.include?("to_label")
|
747
|
+
elsif me.column_names.include?("to_label") || me.instance_methods(false).include?(:to_label)
|
656
748
|
"to_label"
|
657
|
-
elsif me.column_names.include?("full_name")
|
749
|
+
elsif me.column_names.include?("full_name") || me.instance_methods(false).include?(:full_name)
|
658
750
|
"full_name"
|
659
|
-
elsif me.column_names.include?("display_name")
|
751
|
+
elsif me.column_names.include?("display_name") || me.instance_methods(false).include?(:display_name)
|
660
752
|
"display_name"
|
661
|
-
elsif me.column_names.include?("email")
|
753
|
+
elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
|
662
754
|
"email"
|
663
|
-
elsif me.column_names.include?("number")
|
664
|
-
|
665
|
-
|
755
|
+
elsif me.column_names.include?("number") || me.instance_methods(false).include?(:number)
|
756
|
+
"number"
|
666
757
|
else
|
667
|
-
|
758
|
+
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)"
|
759
|
+
raise(HotGlue::Error, exit_message)
|
668
760
|
end
|
669
761
|
end
|
670
762
|
|
@@ -689,7 +781,8 @@ module HotGlue
|
|
689
781
|
|
690
782
|
|
691
783
|
def paginate
|
692
|
-
"
|
784
|
+
"- if #{plural}.respond_to?(:total_pages)
|
785
|
+
= paginate #{plural}"
|
693
786
|
end
|
694
787
|
|
695
788
|
private # thor does something fancy like sending the class all of its own methods during some strange run sequence
|