hot-glue 0.0.2 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +12 -7
- data/Gemfile +4 -9
- data/Gemfile.lock +42 -22
- data/README.md +140 -30
- 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 +250 -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/_line.haml +1 -1
- data/lib/generators/hot_glue/templates/_list.haml +4 -2
- data/lib/generators/hot_glue/templates/_new_button.haml +1 -1
- 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/index.haml +1 -1
- 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 +109 -0
- data/lib/hotglue/version.rb +1 -1
- metadata +17 -6
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,149 +44,192 @@ module HotGlue
|
|
38
44
|
include GeneratorHelper
|
39
45
|
|
40
46
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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 :spacs_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: ""
|
51
65
|
|
66
|
+
def initialize(*meta_args) #:nodoc:
|
67
|
+
super
|
52
68
|
|
53
|
-
|
54
|
-
|
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
|
55
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
|
56
79
|
|
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
80
|
|
63
|
-
|
64
|
-
|
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
|
65
96
|
|
66
|
-
args[1..-1].each do |a|
|
67
|
-
var_name, var_value = a.split("=")
|
68
|
-
case (var_name)
|
69
97
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
@nest = var_value
|
74
|
-
when "namespace"
|
75
|
-
@namespace = var_value
|
76
|
-
when "auth"
|
77
|
-
@auth = var_value
|
78
|
-
when "auth_identifier"
|
79
|
-
@auth_identifier = var_value || ""
|
98
|
+
@show_only = []
|
99
|
+
if !options['show_only'].empty?
|
100
|
+
@show_only += options['show_only'].split(",").collect(&:to_sym)
|
80
101
|
end
|
81
|
-
end
|
82
102
|
|
83
|
-
|
103
|
+
auth_assoc = @auth.gsub("current_","")
|
104
|
+
|
105
|
+
@god = options['god'] || options['gd'] || false
|
106
|
+
@specs_only = options['specs_only'] || false
|
107
|
+
@no_specs = options['no_specs'] || false
|
108
|
+
@no_delete = options['no_delete'] || false
|
84
109
|
|
85
|
-
|
86
|
-
|
110
|
+
@no_create = options['no_create'] || false
|
111
|
+
@no_paginate = options['no_paginate'] || false
|
112
|
+
@big_edit = options['big_edit']
|
87
113
|
|
88
|
-
|
89
|
-
flags.each do |f|
|
90
|
-
case (f)
|
91
|
-
when "--god"
|
114
|
+
if @god
|
92
115
|
@auth = nil
|
93
|
-
# when "--with-index"
|
94
|
-
# @with_index = true
|
95
|
-
when "--specs-only"
|
96
|
-
@specs_only = true
|
97
|
-
when "--no-specs"
|
98
|
-
@no_specs = true
|
99
|
-
when "--no-delete"
|
100
|
-
@no_delete = true
|
101
|
-
when "--no-create"
|
102
|
-
@no_create = true
|
103
116
|
end
|
104
|
-
end
|
105
117
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
118
|
+
# when in self auth, the object is the same as the authenticated object
|
119
|
+
if @auth && auth_identifier == @singular
|
120
|
+
@self_auth = true
|
121
|
+
end
|
110
122
|
|
123
|
+
@nested_args = []
|
124
|
+
if !@nest.nil?
|
125
|
+
@nested_args = @nest.split("/")
|
126
|
+
@nested_args_plural = {}
|
127
|
+
@nested_args.each do |a|
|
128
|
+
@nested_args_plural[a] = a + "s"
|
129
|
+
end
|
130
|
+
end
|
111
131
|
|
112
|
-
|
113
|
-
|
114
|
-
@auth_identifier = @auth.gsub("current_", "")
|
115
|
-
end
|
132
|
+
# the @object_owner will always be object that will 'own' the object
|
133
|
+
# for new and create
|
116
134
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
135
|
+
if @auth && ! @self_auth && @nested_args.none?
|
136
|
+
@object_owner_sym = @auth.gsub("current_", "").to_sym
|
137
|
+
@object_owner_eval = @auth
|
138
|
+
else
|
121
139
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
140
|
+
if @nested_args.any?
|
141
|
+
@object_owner_sym = @nested_args.last.to_sym
|
142
|
+
@object_owner_eval = "@#{@nested_args.last}"
|
143
|
+
else
|
144
|
+
@object_owner_sym = ""
|
145
|
+
@object_owner_eval = ""
|
146
|
+
end
|
127
147
|
end
|
128
|
-
end
|
129
148
|
|
130
|
-
# the @object_owner will always be object that will 'own' the object
|
131
|
-
# for new and create
|
132
149
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
else
|
150
|
+
if !@object_owner_sym.empty?
|
151
|
+
auth_assoc_field = auth_assoc + "_id"
|
152
|
+
assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
|
137
153
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
154
|
+
if assoc
|
155
|
+
ownership_field = assoc.name.to_s + "_id"
|
156
|
+
else
|
157
|
+
# if @auth
|
158
|
+
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."
|
159
|
+
# else
|
160
|
+
# exit_message= "*** Oops: god mode could not find the association(?). something is wrong."
|
161
|
+
# end
|
162
|
+
raise(HotGlue::Error, exit_message)
|
163
|
+
end
|
144
164
|
end
|
145
|
-
end
|
146
165
|
|
166
|
+
if !@include_fields
|
167
|
+
@exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
|
168
|
+
:reset_password_token,
|
169
|
+
:reset_password_sent_at, :remember_created_at,
|
170
|
+
:confirmation_token, :confirmed_at,
|
171
|
+
:confirmation_sent_at, :unconfirmed_email
|
172
|
+
|
173
|
+
@exclude_fields.push(auth_assoc_field.to_sym) if !auth_assoc_field.nil?
|
174
|
+
@exclude_fields.push(ownership_field.to_sym) if !ownership_field.nil?
|
147
175
|
|
148
176
|
|
149
|
-
|
150
|
-
|
151
|
-
auth_assoc_field = auth_assoc + "_id"
|
152
|
-
assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
|
153
|
-
if assoc
|
154
|
-
ownership_field = assoc.name.to_s + "_id"
|
177
|
+
@columns = object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
|
178
|
+
|
155
179
|
else
|
156
|
-
|
157
|
-
|
158
|
-
else
|
159
|
-
puts "*** Oops: god mode could not find the association(?). something is wrong."
|
160
|
-
end
|
161
|
-
exit
|
180
|
+
@columns = object.columns.map(&:name).map(&:to_sym).reject{|field| !@include_fields.include?(field) }
|
181
|
+
|
162
182
|
end
|
163
|
-
end
|
164
183
|
|
165
|
-
|
166
|
-
|
167
|
-
|
184
|
+
@columns.each do |col|
|
185
|
+
if col.to_s.starts_with?("_")
|
186
|
+
@show_only << col
|
187
|
+
end
|
168
188
|
|
169
|
-
|
170
|
-
|
189
|
+
if object.columns_hash[col.to_s].type == :integer
|
190
|
+
if col.to_s.ends_with?("_id")
|
191
|
+
# guess the association name label
|
192
|
+
assoc_name = col.to_s.gsub("_id","")
|
193
|
+
assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
171
194
|
|
172
195
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
196
|
+
begin
|
197
|
+
eval(assoc.class_name)
|
198
|
+
rescue NameError => e
|
199
|
+
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} "
|
200
|
+
raise(HotGlue::Error, exit_message)
|
179
201
|
|
202
|
+
end
|
180
203
|
|
181
204
|
|
205
|
+
if assoc.nil?
|
206
|
+
exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
207
|
+
raise(HotGlue::Error,exit_message)
|
208
|
+
end
|
209
|
+
|
210
|
+
assoc_class = eval(assoc.class_name)
|
211
|
+
if assoc_class.respond_to?(:name)
|
212
|
+
# display_column = "name"
|
213
|
+
elsif assoc_class.respond_to?(:to_label)
|
214
|
+
# display_column = "to_label"
|
215
|
+
elsif assoc_class.respond_to?(:full_name)
|
216
|
+
# display_column = "full_name"
|
217
|
+
elsif assoc_class.respond_to?(:display_name)
|
218
|
+
# display_column = "display_name"
|
219
|
+
elsif assoc_class.respond_to?(:email)
|
220
|
+
# display_column = "email"
|
221
|
+
else
|
222
|
+
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)"
|
223
|
+
raise(HotGlue::Error,exit_message)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
182
228
|
end
|
183
229
|
|
230
|
+
|
231
|
+
|
232
|
+
#
|
184
233
|
def formats
|
185
234
|
[format]
|
186
235
|
end
|
@@ -193,17 +242,19 @@ module HotGlue
|
|
193
242
|
@default_colspan = @columns.size
|
194
243
|
|
195
244
|
unless @specs_only
|
196
|
-
template "controller.rb", File.join("app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
|
245
|
+
template "controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
|
197
246
|
if @namespace && defined?(controller_descends_from) == nil
|
198
|
-
template "base_controller.rb", File.join("app/controllers#{namespace_with_dash}", "base_controller.rb")
|
247
|
+
template "base_controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "base_controller.rb")
|
199
248
|
end
|
200
249
|
end
|
201
250
|
|
202
251
|
unless @no_specs
|
203
|
-
template "
|
252
|
+
template "request_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/request#{namespace_with_dash}", "#{plural}_spec.rb")
|
253
|
+
template "system_spec.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_spec.rb")
|
254
|
+
|
204
255
|
end
|
205
256
|
|
206
|
-
template "_errors.haml", File.join("app/views#{namespace_with_dash}", "_errors.haml")
|
257
|
+
template "_errors.haml", File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", "_errors.haml")
|
207
258
|
end
|
208
259
|
|
209
260
|
def list_column_headings
|
@@ -311,6 +362,18 @@ module HotGlue
|
|
311
362
|
"#{@namespace+"/" if @namespace}#{plural}/line"
|
312
363
|
end
|
313
364
|
|
365
|
+
def show_path_partial
|
366
|
+
"#{@namespace+"/" if @namespace}#{plural}/show"
|
367
|
+
end
|
368
|
+
|
369
|
+
def list_path_partial
|
370
|
+
"#{@namespace+"/" if @namespace}#{plural}/list"
|
371
|
+
end
|
372
|
+
|
373
|
+
def new_path_name
|
374
|
+
"new_#{@namespace+"_" if @namespace}#{singular}_path"
|
375
|
+
end
|
376
|
+
|
314
377
|
def nested_assignments
|
315
378
|
@nested_args.map{|a| "#{a}: @#{a}"}.join(", ") #metaprgramming into Ruby hash
|
316
379
|
end
|
@@ -386,14 +449,14 @@ module HotGlue
|
|
386
449
|
haml_views.each do |view|
|
387
450
|
formats.each do |format|
|
388
451
|
filename = cc_filename_with_extensions(view, "haml")
|
389
|
-
template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
|
452
|
+
template filename, File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", controller_file_path, filename)
|
390
453
|
end
|
391
454
|
end
|
392
455
|
|
393
456
|
turbo_stream_views.each do |view|
|
394
457
|
formats.each do |format|
|
395
458
|
filename = cc_filename_with_extensions(view, 'turbo_stream.haml')
|
396
|
-
template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
|
459
|
+
template filename, File.join("#{'spec/dummy/' if Rails.env.test?}app/views#{namespace_with_dash}", controller_file_path, filename)
|
397
460
|
end
|
398
461
|
end
|
399
462
|
end
|
@@ -415,13 +478,21 @@ module HotGlue
|
|
415
478
|
end
|
416
479
|
|
417
480
|
def haml_views
|
418
|
-
res = %w(index edit
|
481
|
+
res = %w(index edit _form _line _list _show _errors)
|
482
|
+
|
483
|
+
unless @no_create
|
484
|
+
res += %w(new _new_form _new_button)
|
485
|
+
end
|
419
486
|
|
420
487
|
res
|
421
488
|
end
|
422
489
|
|
423
490
|
def turbo_stream_views
|
424
|
-
res = %w(create
|
491
|
+
res = %w(create edit update)
|
492
|
+
unless @no_delete
|
493
|
+
res << 'destroy'
|
494
|
+
end
|
495
|
+
res
|
425
496
|
end
|
426
497
|
|
427
498
|
def handler
|
@@ -442,6 +513,16 @@ module HotGlue
|
|
442
513
|
col_spaces_prepend = " "
|
443
514
|
|
444
515
|
res = @columns.map { |col|
|
516
|
+
|
517
|
+
if @show_only.include?(col)
|
518
|
+
|
519
|
+
"#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
|
520
|
+
= @#{singular}.#{col.to_s}
|
521
|
+
%label.form-text
|
522
|
+
#{col.to_s.humanize}\n"
|
523
|
+
else
|
524
|
+
|
525
|
+
|
445
526
|
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
446
527
|
limit = eval("#{singular_class}.columns_hash['#{col}']").limit
|
447
528
|
sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
|
@@ -450,43 +531,41 @@ module HotGlue
|
|
450
531
|
when :integer
|
451
532
|
# look for a belongs_to on this object
|
452
533
|
if col.to_s.ends_with?("_id")
|
453
|
-
# guess the association name label
|
454
|
-
|
455
|
-
|
456
534
|
assoc_name = col.to_s.gsub("_id","")
|
457
535
|
assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
458
536
|
if assoc.nil?
|
459
|
-
|
537
|
+
exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
460
538
|
exit
|
461
539
|
end
|
462
540
|
|
463
541
|
|
464
542
|
assoc_class = eval(assoc.class_name)
|
465
543
|
|
466
|
-
if assoc_class.
|
544
|
+
if assoc_class.respond_to?("name")
|
467
545
|
display_column = "name"
|
468
|
-
elsif assoc_class.
|
546
|
+
elsif assoc_class.respond_to?("to_label")
|
469
547
|
display_column = "to_label"
|
470
|
-
elsif assoc_class.
|
548
|
+
elsif assoc_class.respond_to?("full_name")
|
471
549
|
display_column = "full_name"
|
472
|
-
elsif assoc_class.
|
550
|
+
elsif assoc_class.respond_to?("display_name")
|
473
551
|
display_column = "display_name"
|
474
|
-
elsif assoc_class.
|
552
|
+
elsif assoc_class.respond_to?("email")
|
475
553
|
display_column = "email"
|
476
554
|
else
|
477
|
-
|
555
|
+
raise("this should have been caught by the checker in the initializer")
|
556
|
+
# 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)"
|
478
557
|
end
|
479
558
|
|
480
559
|
"#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{assoc_name.to_s})}\"}
|
481
560
|
#{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')
|
482
|
-
#{col_spaces_prepend}
|
483
|
-
#{col_spaces_prepend}
|
561
|
+
#{col_spaces_prepend}%label.small.form-text.text-muted
|
562
|
+
#{col_spaces_prepend} #{col.to_s.humanize}"
|
484
563
|
|
485
564
|
else
|
486
565
|
"#{col_identifier}{class: \"form-group \#{'alert-danger' if @#{singular}.errors.details.keys.include?(:#{col.to_s})}\"}
|
487
566
|
#{col_spaces_prepend}= f.text_field :#{col.to_s}, value: #{singular}.#{col.to_s}, class: 'form-control', size: 4, type: 'number'
|
488
|
-
#{col_spaces_prepend}
|
489
|
-
#{col_spaces_prepend}
|
567
|
+
#{col_spaces_prepend}%label.form-text
|
568
|
+
#{col_spaces_prepend} #{col.to_s.humanize}\n"
|
490
569
|
end
|
491
570
|
when :string
|
492
571
|
limit ||= 256
|
@@ -528,7 +607,7 @@ module HotGlue
|
|
528
607
|
#{col_spaces_prepend}= f.label(:#{col.to_s}, value: 'Yes', for: '#{singular}_#{col.to_s}_1')
|
529
608
|
"
|
530
609
|
end
|
531
|
-
|
610
|
+
end
|
532
611
|
}.join("\n")
|
533
612
|
return res
|
534
613
|
end
|
@@ -555,24 +634,27 @@ module HotGlue
|
|
555
634
|
assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
556
635
|
|
557
636
|
if assoc.nil?
|
558
|
-
|
559
|
-
|
637
|
+
exit_message = "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
638
|
+
raise(HotGlue::Error,exit_message)
|
560
639
|
end
|
561
640
|
|
562
641
|
assoc_class = eval(assoc.class_name)
|
563
642
|
|
564
|
-
if assoc_class.
|
643
|
+
if assoc_class.respond_to?("name")
|
565
644
|
display_column = "name"
|
566
|
-
elsif assoc_class.
|
645
|
+
elsif assoc_class.respond_to?("to_label")
|
567
646
|
display_column = "to_label"
|
568
|
-
elsif assoc_class.
|
647
|
+
elsif assoc_class.respond_to?("full_name")
|
569
648
|
display_column = "full_name"
|
570
|
-
elsif assoc_class.
|
649
|
+
elsif assoc_class.respond_to?("display_name")
|
571
650
|
display_column = "display_name"
|
572
|
-
elsif assoc_class.
|
651
|
+
elsif assoc_class.respond_to?("email")
|
573
652
|
display_column = "email"
|
653
|
+
elsif assoc_class.respond_to?("number")
|
654
|
+
display_column = "number"
|
655
|
+
|
574
656
|
else
|
575
|
-
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,
|
657
|
+
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)"
|
576
658
|
end
|
577
659
|
|
578
660
|
"#{col_identifer}
|
@@ -642,6 +724,30 @@ module HotGlue
|
|
642
724
|
end
|
643
725
|
|
644
726
|
|
727
|
+
|
728
|
+
def display_class
|
729
|
+
me = eval(singular_class)
|
730
|
+
|
731
|
+
@display_class ||=
|
732
|
+
if me.respond_to?("name")
|
733
|
+
"name"
|
734
|
+
elsif me.respond_to?("to_label")
|
735
|
+
"to_label"
|
736
|
+
elsif me.respond_to?("full_name")
|
737
|
+
"full_name"
|
738
|
+
elsif me.respond_to?("display_name")
|
739
|
+
"display_name"
|
740
|
+
elsif me.respond_to?("email")
|
741
|
+
"email"
|
742
|
+
elsif me.respond_to?("number")
|
743
|
+
display_column = "number"
|
744
|
+
|
745
|
+
else
|
746
|
+
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)"
|
747
|
+
raise(HotGlue::Error, exit_message)
|
748
|
+
end
|
749
|
+
end
|
750
|
+
|
645
751
|
def destroy_action
|
646
752
|
return false if @self_auth
|
647
753
|
return !@no_delete
|
@@ -660,7 +766,13 @@ module HotGlue
|
|
660
766
|
end
|
661
767
|
end
|
662
768
|
|
663
|
-
|
769
|
+
|
770
|
+
|
771
|
+
def paginate
|
772
|
+
"= paginate #{plural}"
|
773
|
+
end
|
774
|
+
|
775
|
+
private # thor does something fancy like sending the class all of its own methods during some strange run sequence
|
664
776
|
# does not like public methods
|
665
777
|
|
666
778
|
def cc_filename_with_extensions(name, file_format = format)
|