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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -1
- data/.gitignore +12 -7
- data/Gemfile +4 -9
- data/Gemfile.lock +40 -23
- data/README.md +123 -31
- 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_hgis.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 +230 -138
- data/lib/generators/hot_glue/templates/_errors.haml +6 -5
- data/lib/generators/hot_glue/templates/_flash_notices.haml +7 -6
- data/lib/generators/hot_glue/templates/_new_form.haml +10 -0
- data/lib/generators/hot_glue/templates/_show.haml +1 -1
- 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} +11 -7
- data/lib/generators/hot_glue/templates/create.turbo_stream.haml +12 -3
- data/lib/generators/hot_glue/templates/edit.haml +2 -0
- data/lib/generators/hot_glue/templates/new.haml +1 -10
- data/lib/generators/hot_glue/templates/{controller_spec.rb → request_spec.rb.erb} +0 -0
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +53 -0
- data/lib/hotglue/version.rb +1 -1
- 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("
|
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 "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 "
|
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,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
|
-
|
42
|
-
|
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
|
-
|
45
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
98
|
+
@show_only = []
|
99
|
+
if !options['show_only'].empty?
|
100
|
+
@show_only += options['show_only'].split(",").collect(&:to_sym)
|
101
|
+
end
|
66
102
|
|
67
|
-
|
68
|
-
var_name, var_value = a.split("=")
|
69
|
-
case (var_name)
|
103
|
+
auth_assoc = @auth.gsub("current_","")
|
70
104
|
|
71
|
-
|
72
|
-
|
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
|
-
|
108
|
+
@no_specs = options['no_specs'] || false
|
109
|
+
@no_delete = options['no_delete'] || false
|
87
110
|
|
88
|
-
|
89
|
-
|
111
|
+
@no_create = options['no_create'] || false
|
112
|
+
@no_paginate = options['no_paginate'] || false
|
113
|
+
@big_edit = options['big_edit']
|
90
114
|
|
91
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
-
|
116
|
-
|
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
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
153
|
-
|
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
|
-
|
160
|
-
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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
|
-
|
175
|
-
|
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 "
|
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
|
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
|
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
|
-
|
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.
|
543
|
+
if assoc_class.respond_to?("name")
|
483
544
|
display_column = "name"
|
484
|
-
elsif assoc_class.
|
545
|
+
elsif assoc_class.respond_to?("to_label")
|
485
546
|
display_column = "to_label"
|
486
|
-
elsif assoc_class.
|
547
|
+
elsif assoc_class.respond_to?("full_name")
|
487
548
|
display_column = "full_name"
|
488
|
-
elsif assoc_class.
|
549
|
+
elsif assoc_class.respond_to?("display_name")
|
489
550
|
display_column = "display_name"
|
490
|
-
elsif assoc_class.
|
551
|
+
elsif assoc_class.respond_to?("email")
|
491
552
|
display_column = "email"
|
492
553
|
else
|
493
|
-
|
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
|
-
|
575
|
-
|
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.
|
642
|
+
if assoc_class.respond_to?("name")
|
581
643
|
display_column = "name"
|
582
|
-
elsif assoc_class.
|
644
|
+
elsif assoc_class.respond_to?("to_label")
|
583
645
|
display_column = "to_label"
|
584
|
-
elsif assoc_class.
|
646
|
+
elsif assoc_class.respond_to?("full_name")
|
585
647
|
display_column = "full_name"
|
586
|
-
elsif assoc_class.
|
648
|
+
elsif assoc_class.respond_to?("display_name")
|
587
649
|
display_column = "display_name"
|
588
|
-
elsif assoc_class.
|
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,
|
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
|
-
"
|
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
|