hot-glue 0.4.4 → 0.4.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/README2.md ADDED
@@ -0,0 +1,79 @@
1
+
2
+ ## LEGACY SETUP FOR RAILS 6
3
+
4
+ ## Legacy Step #1. ADD HOTWIRE
5
+ (RAILS 6 ONLY— SKIP THIS STEP FOR RAILS 7)
6
+ ```
7
+ yarn add @hotwired/turbo-rails
8
+ ```
9
+ or `npm install @hotwired/turbo-rails`
10
+
11
+
12
+ ## Legacy Step #2. SWITCH FROM TurblLinks to Turbo-Rails
13
+ (RAILS 6 ONLY — SKIP FOR RAILS 7)
14
+ (THIS WAS AUTOMATICALLY DONE BY THE HOT GLUE INSTALLATION -- CONFIRM CHANGES ONLY)
15
+ - Add `gem 'turbo-rails'` to your Gemfile & `bundle install`
16
+ - Then install it with `rails turbo:install`
17
+ - The Turbo install has switched your action cable settings from 'async' to Redis, so be sure to start a redis server
18
+ - in `app/javascript/packs/application.js` remove this line
19
+ ```
20
+ import Turbolinks from "turbolinks"
21
+ ```
22
+ and replace it with
23
+ ```
24
+ import { Turbo } from "@hotwired/turbo-rails"
25
+ ```
26
+
27
+
28
+ Also replace
29
+ ```
30
+ Turbolinks.start()
31
+ ```
32
+ with:
33
+ ```
34
+ Turbo.start()
35
+ ```
36
+
37
+
38
+ ## Legacy Step #3. INSTALL WEBPACKER
39
+ (_SKIP FOR RAILS 7_ unless you want to use Webpacker with Rails 7)
40
+
41
+ ** For webpacker, you must be using Node version ^12.13.0 || ^14.15.0 || >=16 **
42
+
43
+ I recommend Node Version Manager (NVM) to switch between nodes. You will not be able to get through the following command with a Node version that does not match above.
44
+
45
+ Check your node version with `node -v`
46
+
47
+ ```
48
+ `yarn add @rails/webpacker`
49
+ ```
50
+
51
+
52
+ rails webpacker:install
53
+
54
+ ## Legacy Step #4: Postgresql Enum Support for Rail 6
55
+ For Enum support, I recommend activerecord-pg_enum
56
+ Instructions for Rails 6 are here:
57
+ https://jasonfleetwoodboldt.com/courses/stepping-up-rails/enumerated-types-in-rails-and-postgres/
58
+
59
+ _This functionality is now built-in to Rails 7._
60
+
61
+
62
+ ## Legacy Step #5: Fix Devise if adding Turbo To Your Project
63
+ ## IMPORTANT: Devise currently has serious compatibility issues with Turbo Rails. In particular, your log-in screens do not work out of the box. Follow the next step to fix them.
64
+
65
+ Manually port the Devise views into your app with
66
+
67
+ `rails generate devise:views`
68
+
69
+ Edit `devise/registrations/new`, `devise/sessions/new`, `devise/passwords/new` and `devise/confirmations/new` modifying all four templates like so:
70
+
71
+ form_for(resource, as: resource_name, url: session_path(resource_name) ) do |f|
72
+
73
+ add the data-turbo false option in the html key:
74
+ ```bigquery
75
+
76
+ ```
77
+ form_for(resource, as: resource_name, **html: {'data-turbo' => "false"},** url: session_path(resource_name) ) do |f|
78
+
79
+ This tells Devise to fall back to non-Turbo interaction for the log-in and registration. For the rest of the app, we will use Turbo Rails interactions.
data/config/database.yml CHANGED
@@ -1,86 +1,11 @@
1
- # PostgreSQL. Versions 9.3 and up are supported.
2
- #
3
- # Install the pg driver:
4
- # gem install pg
5
- # On macOS with Homebrew:
6
- # gem install pg -- --with-pg-config=/usr/local/bin/pg_config
7
- # On macOS with MacPorts:
8
- # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
9
- # On Windows:
10
- # gem install pg
11
- # Choose the win32 build.
12
- # Install PostgreSQL and put its /bin directory on your path.
13
- #
14
- # Configure Using Gemfile
15
- # gem 'pg'
16
- #
17
- default: &default
18
- adapter: postgresql
19
- encoding: unicode
20
- # For details on connection pooling, see Rails configuration guide
21
- # https://guides.rubyonrails.org/configuring.html#database-pooling
22
- pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
23
-
24
1
  development:
25
- <<: *default
26
- database: Dummy_development
27
-
28
- # The specified database role being used to connect to postgres.
29
- # To create additional roles in postgres see `$ createuser --help`.
30
- # When left blank, postgres will use the default role. This is
31
- # the same name as the operating system user running Rails.
32
- #username: Dummy
33
-
34
- # The password associated with the postgres role (username).
35
- #password:
36
-
37
- # Connect on a TCP socket. Omitted by default since the client uses a
38
- # domain socket that doesn't need configuration. Windows does not have
39
- # domain sockets, so uncomment these lines.
40
- #host: localhost
2
+ adapter: sqlite3
3
+ database: ../spec/dummy/db/development.sqlite3
4
+ pool: 5
5
+ timeout: 5000
41
6
 
42
- # The TCP port the server listens on. Defaults to 5432.
43
- # If your server runs on a different port number, change accordingly.
44
- #port: 5432
45
-
46
- # Schema search path. The server defaults to $user,public
47
- #schema_search_path: myapp,sharedapp,public
48
-
49
- # Minimum log levels, in increasing order:
50
- # debug5, debug4, debug3, debug2, debug1,
51
- # log, notice, warning, error, fatal, and panic
52
- # Defaults to warning.
53
- #min_messages: notice
54
-
55
- # Warning: The database defined as "test" will be erased and
56
- # re-generated from your development database when you run "rake".
57
- # Do not set this db to the same as development or production.
58
7
  test:
59
- <<: *default
60
- database: Dummy_test
61
-
62
- # As with config/credentials.yml, you never want to store sensitive information,
63
- # like your database password, in your source code. If your source code is
64
- # ever seen by anyone, they now have access to your database.
65
- #
66
- # Instead, provide the password or a full connection URL as an environment
67
- # variable when you boot the app. For example:
68
- #
69
- # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
70
- #
71
- # If the connection URL is provided in the special DATABASE_URL environment
72
- # variable, Rails will automatically merge its configuration values on top of
73
- # the values provided in this file. Alternatively, you can specify a connection
74
- # URL environment variable explicitly:
75
- #
76
- # production:
77
- # url: <%= ENV['MY_APP_DATABASE_URL'] %>
78
- #
79
- # Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
80
- # for a full overview on how database connection configuration can be specified.
81
- #
82
- production:
83
- <<: *default
84
- database: Dummy_production
85
- username: Dummy
86
- password: <%= ENV['DUMMY_DATABASE_PASSWORD'] %>
8
+ adapter: sqlite3
9
+ database: ../spec/dummy/db/test.sqlite3
10
+ pool: 5
11
+ timeout: 5000
data/db/schema.rb ADDED
@@ -0,0 +1 @@
1
+ db/spec/dummy/db/schema.rb
@@ -17,7 +17,6 @@ module HotGlue
17
17
  super
18
18
  @layout = options['layout'] || "hotglue"
19
19
  @theme = options['theme']
20
-
21
20
  if @layout == "hotglue" && options['theme'].nil?
22
21
  puts "You have selected to install Hot Glue without a theme. You can either use the --layout=bootstrap to install NO HOT GLUE THEME, or to use a Hot Glue theme please choose: like_boostrap, like_menlo_park, like_cupertino, like_mountain_view, dark_knight"
23
22
  return
@@ -3,27 +3,33 @@
3
3
  module HotGlue
4
4
  module Layout
5
5
  class Builder
6
- attr_reader :include_setting, :downnest_children, :no_edit, :no_delete, :columns, :smart_layout
6
+ attr_reader :include_setting,
7
+ :downnest_children,
8
+ :buttons_width, :columns,
9
+ :smart_layout, :specified_grouping_mode
7
10
 
8
11
  def initialize(params)
9
12
  @include_setting = params[:include_setting]
10
13
  @downnest_children = params[:downnest_children]
11
- @no_edit = params[:no_edit]
12
- @no_delete = params[:no_delete]
14
+
15
+ @buttons_width = params[:buttons_width]
16
+
17
+ @no_buttons = @buttons_width == 0
13
18
  @columns = params[:columns]
14
19
  @smart_layout = params[:smart_layout]
20
+ @specified_grouping_mode = include_setting.include?(":")
15
21
  end
16
22
 
17
23
  def construct
18
24
  layout_object = {
19
25
  columns: {
20
- size_each: nil,
26
+ size_each: smart_layout ? 2 : (specified_grouping_mode ? nil : 1),
21
27
  container: [] # array of arrays
22
28
  },
23
29
  portals: {
24
30
 
25
31
  },
26
- buttons: { size: ''}
32
+ buttons: { size: @buttons_width}
27
33
  }
28
34
 
29
35
  downnest_children.each do |child|
@@ -32,9 +38,8 @@ module HotGlue
32
38
 
33
39
  # smart layout: 2 columns per field; 4 column for EACH downnested portals, 2 column for buttons
34
40
  how_many_downnest = downnest_children.size
35
- button_column_size = (no_edit && no_delete) ? 0 : 2
36
41
 
37
- bootstrap_columns = (12-button_column_size)
42
+ bootstrap_columns = (12-@buttons_width )
38
43
  bootstrap_columns = bootstrap_columns - (how_many_downnest*4)
39
44
  available_columns = (bootstrap_columns / 2).floor # bascially turns the 12-column grid into a 6-column grid
40
45
 
@@ -45,9 +50,6 @@ module HotGlue
45
50
  @downnest_children_width = []
46
51
  @downnest_children.each_with_index{ |child, i| @downnest_children_width[i] = 4}
47
52
 
48
- if include_setting.nil?
49
-
50
- end
51
53
 
52
54
  if smart_layout
53
55
  # automatic control
@@ -55,7 +57,7 @@ module HotGlue
55
57
 
56
58
  if columns.size > available_columns
57
59
  each_col_can_have = (columns.size.to_f / available_columns.to_f).round
58
- # byebug
60
+
59
61
  layout_object[:columns][:container] = (0..available_columns-1).collect { |x|
60
62
  columns.slice(0+(x*each_col_can_have),each_col_can_have)
61
63
  }
@@ -67,22 +69,29 @@ module HotGlue
67
69
  }
68
70
  layout_object[:columns][:container].reject!{|x| x == [nil]}
69
71
  end
70
- elsif !include_setting.include?(":")
72
+ elsif ! specified_grouping_mode
73
+ # not smart and no specified grouping
74
+ #
71
75
  layout_object[:columns][:container] = columns.collect{|col| [col]}
72
76
 
73
- else
77
+ else # specified grouping mode -- the builder is given control
78
+
74
79
  (0..available_columns-1).each do |int|
75
80
  layout_object[:columns][:container][int] = []
76
81
  end
77
82
 
78
83
  # input control
79
- user_layout_columns = options['include'].split(":")
84
+
85
+ user_layout_columns = @include_setting.split(":")
86
+ size_each = (bootstrap_columns / user_layout_columns.count).floor # this is the bootstrap size
87
+
88
+ layout_object[:columns][:size_each] = size_each
80
89
 
81
90
  if user_layout_columns.size > available_columns
82
- raise "Your include statement #{options['include']} has #{user_layout_columns.size} columns, but I can only construct up to #{available_columns}"
91
+ raise "Your include statement #{@include_setting } has #{user_layout_columns.size} columns, but I can only construct up to #{available_columns}"
83
92
  end
84
93
  user_layout_columns.each_with_index do |column,i|
85
- layout_object[:columns][:container][i] = column.split(",")
94
+ layout_object[:columns][:container][i] = column.split(",").collect(&:to_sym)
86
95
  end
87
96
 
88
97
  if user_layout_columns.size < layout_object[:columns][:container].size
@@ -90,21 +99,23 @@ module HotGlue
90
99
  end
91
100
  end
92
101
 
93
- if layout_object[:columns][:container].size < available_columns
94
- available = available_columns - layout_object[:columns][:container].size
95
- downnest_child_count = 0
96
-
97
- while(available > 0)
98
- if (downnest_child_count <= downnest_children.size-1)
99
- layout_object[:portals][downnest_children[downnest_child_count]][:size] = layout_object[:portals][downnest_children[downnest_child_count]][:size] + 2
100
- else
101
- # leave as-is
102
- end
103
- downnest_child_count = downnest_child_count + 1
104
- available = available - 1
105
- end
106
- # give some space back to the downnest
107
- end
102
+ # TODO: do I want this code that expands the downnest portal
103
+ # maybe refactor into a setting on the --downnest flag itself somehow
104
+ # if layout_object[:columns][:container].size < available_columns
105
+ # available = available_columns - layout_object[:columns][:container].size
106
+ # downnest_child_count = 0
107
+ #
108
+ # while(available > 0)
109
+ # if (downnest_child_count <= downnest_children.size-1)
110
+ # layout_object[:portals][downnest_children[downnest_child_count]][:size] = layout_object[:portals][downnest_children[downnest_child_count]][:size] + 2
111
+ # else
112
+ # # leave as-is
113
+ # end
114
+ # downnest_child_count = downnest_child_count + 1
115
+ # available = available - 1
116
+ # end
117
+ # # give some space back to the downnest
118
+ # end
108
119
 
109
120
  puts "*** constructed layout columns #{layout_object.inspect}"
110
121
  layout_object
@@ -1,25 +1,35 @@
1
1
  module HotGlue
2
2
  class ErbTemplate < TemplateBase
3
3
 
4
+
5
+
6
+ def add_spaces_each_line(text, num_spaces)
7
+ add_spaces = " " * num_spaces
8
+ text.lines.collect{|line| add_spaces + line}.join("")
9
+ end
10
+
11
+
4
12
  # include GeneratorHelper
5
13
  attr_accessor :singular
6
14
 
7
15
  def field_output(col, type = nil, width, col_identifier )
8
- " <%= f.text_field :#{col.to_s}, value: @#{@singular}.#{col.to_s}, autocomplete: 'off', size: #{width}, class: 'form-control', type: '#{type}' %>\n "+
9
- " <label class='form-text' >#{col.to_s.humanize}</label>\n"
16
+ " <%= f.text_field :#{col}, value: @#{@singular}.#{col}, autocomplete: 'off', size: #{width}, class: 'form-control', type: '#{type}' %>\n "+
17
+ "\n"
10
18
  end
11
19
 
12
20
 
13
21
  def magic_button_output(*args)
14
- path_helper_singular = args[0][:path_helper_singular]
15
- path_helper_args = args[0][:path_helper_args]
22
+ path = args[0][:path]
23
+ # path_helper_singular = args[0][:path_helper_singular]
24
+ # path_helper_args = args[0][:path_helper_args]
16
25
  singular = args[0][:singular]
17
26
  magic_buttons = args[0][:magic_buttons]
27
+ small_buttons = args[0][:small_buttons]
18
28
 
19
29
  magic_buttons.collect{ |button_name|
20
- "<%= form_with model: #{singular}, url: #{path_helper_singular}(#{path_helper_args}) do |f| %>
30
+ "<%= form_with model: #{singular}, url: #{path}, html: {style: 'display: inline', data: {\"turbo-confirm\": 'Are you sure you want to #{button_name} this #{singular}?'}} do |f| %>
21
31
  <%= f.hidden_field :#{button_name}, value: \"#{button_name}\" %>
22
- <%= f.submit '#{button_name.titleize}'.html_safe, disabled: (#{singular}.respond_to?(:#{button_name}able?) && ! #{singular}.#{button_name}able? ), data: {confirm: 'Are you sure you want to #{button_name} this #{singular}?'}, class: '#{singular}-button btn btn-primary ' %>
32
+ <%= f.submit '#{button_name.titleize}'.html_safe, disabled: (#{singular}.respond_to?(:#{button_name}able?) && ! #{singular}.#{button_name}able? ), class: '#{singular}-button btn btn-primary #{"btn-sm" if small_buttons}' %>
23
33
  <% end %>"
24
34
  }.join("\n")
25
35
  end
@@ -30,8 +40,7 @@ module HotGlue
30
40
  lines = 5
31
41
  end
32
42
 
33
- "<%= f.text_area :#{col.to_s}, class: 'form-control', autocomplete: 'off', cols: 40, rows: '#{lines}' %>" +
34
- "<label class='form-text'>#{col.to_s.humanize}</label>"
43
+ "<%= f.text_area :#{col}, class: 'form-control', autocomplete: 'off', cols: 40, rows: '#{lines}' %>"
35
44
  end
36
45
 
37
46
  def list_column_headings(*args)
@@ -58,90 +67,92 @@ module HotGlue
58
67
  show_only = args[0][:show_only]
59
68
  singular_class = args[0][:singular_class]
60
69
  col_identifier = args[0][:col_identifier]
70
+ ownership_field = args[0][:ownership_field]
61
71
 
62
-
63
- # TODO: CLEAN ME
64
72
  @singular = args[0][:singular]
65
73
  singular = @singular
66
-
67
- col_spaces_prepend = " "
68
-
69
-
70
74
  result = layout_columns.map{ |column|
71
- "<div class='#{col_identifier}' >" +
72
-
75
+ " <div class='#{col_identifier}' >" +
73
76
  column.map { |col|
77
+ field_result =
78
+ if show_only.include?(col.to_sym)
79
+ "<%= @#{singular}.#{col} %>"
80
+ else
81
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
82
+ limit = eval("#{singular_class}.columns_hash['#{col}']").limit
83
+ sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
84
+
85
+ case type
86
+ when :integer
87
+ # look for a belongs_to on this object
88
+ if col.to_s.ends_with?("_id")
89
+ assoc_name = col.to_s.gsub("_id","")
90
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
91
+ if assoc.nil?
92
+ exit_message = "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
93
+ exit
94
+ end
95
+
96
+ is_owner = col == ownership_field
97
+ display_column = HotGlue.derrive_reference_name(assoc.class_name)
98
+
99
+ # TODO: add is_owner && check if this nested arg is optional
100
+ (is_owner ? "<% unless @#{assoc_name} %>\n" : "") +
101
+ " <%= f.collection_select(:#{col}, #{assoc.class_name}.all, :id, :#{display_column}, {prompt: true, selected: @#{singular}.#{col} }, class: 'form-control') %>\n" +
102
+ (is_owner ? "<% else %>\n <%= @#{assoc_name}.#{display_column} %>" : "") +
103
+ (is_owner ? "\n<% end %>" : "")
104
+
105
+ else
106
+ "<%= f.text_field :#{col}, value: #{singular}.#{col}, class: 'form-control', size: 4, type: 'number' %>"
74
107
 
75
- field_result = if show_only.include?(col)
76
- "<%= @#{singular}.#{col.to_s} %>" +
77
- "<label class='form-text'>#{col.to_s.humanize}</label>"
78
- else
79
- type = eval("#{singular_class}.columns_hash['#{col}']").type
80
- limit = eval("#{singular_class}.columns_hash['#{col}']").limit
81
- sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
82
-
83
- case type
84
- when :integer
85
- # look for a belongs_to on this object
86
- if col.to_s.ends_with?("_id")
87
- assoc_name = col.to_s.gsub("_id","")
88
- assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
89
- if assoc.nil?
90
- exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
91
- exit
92
108
  end
93
- display_column = HotGlue.derrive_reference_name(assoc.class_name)
94
- "<%= f.collection_select(:#{col.to_s}, #{assoc.class_name}.all, :id, :#{display_column}, {prompt: true, selected: @#{singular}.#{col.to_s} }, class: 'form-control') %>
95
- <label class='small form-text text-muted'>#{col.to_s.humanize}</label>"
96
-
97
- else
98
- "<%= f.text_field :#{col.to_s}, value: #{singular}.#{col.to_s}, class: 'form-control', size: 4, type: 'number' %>
99
- <label class='small form-text text-muted'>#{col.to_s.humanize}</label>"
109
+ when :string
110
+ if sql_type == "varchar" || sql_type == "character varying"
111
+ field_output(col, nil, limit || 40, col_identifier)
112
+ else
113
+ text_area_output(col, 65536, col_identifier)
114
+ end
100
115
 
101
- end
102
- when :string
103
- if sql_type == "varchar" || sql_type == "character varying"
104
- field_output(col, nil, limit || 40, col_identifier)
105
- else
106
- text_area_output(col, 65536, col_identifier)
116
+ when :text
117
+ if sql_type == "varchar"
118
+ field_output(col, nil, limit, col_identifier)
119
+ else
120
+ text_area_output(col, 65536, col_identifier)
121
+ end
122
+ when :float
123
+ field_output(col, nil, 5, col_identifier)
124
+ when :datetime
125
+ "<%= datetime_field_localized(f, :#{col}, #{singular}.#{col}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
126
+ when :date
127
+ "<%= date_field_localized(f, :#{col}, #{singular}.#{col}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
128
+ when :time
129
+ "<%= time_field_localized(f, :#{col}, #{singular}.#{col}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
130
+ when :boolean
131
+ " " +
132
+ " <span>#{col.to_s.humanize}</span>" +
133
+ " <%= f.radio_button(:#{col}, '0', checked: #{singular}.#{col} ? '' : 'checked') %>\n" +
134
+ " <%= f.label(:#{col}, value: 'No', for: '#{singular}_#{col}_0') %>\n" +
135
+ " <%= f.radio_button(:#{col}, '1', checked: #{singular}.#{col} ? 'checked' : '') %>\n" +
136
+ " <%= f.label(:#{col}, value: 'Yes', for: '#{singular}_#{col}_1') %>\n" +
137
+ ""
138
+ when :enum
139
+ enum_type = eval("#{singular_class}.columns.select{|x| x.name == '#{col}'}[0].sql_type")
140
+ "<%= f.collection_select(:#{col}, enum_to_collection_select( #{singular_class}.defined_enums['#{enum_type}']), :key, :value, {selected: @#{singular}.#{col} }, class: 'form-control') %>"
107
141
  end
108
142
 
109
- when :text
110
- if sql_type == "varchar"
111
- field_output(col, nil, limit, col_identifier)
112
- else
113
- text_area_output(col, 65536, col_identifier)
114
- end
115
- when :float
116
- field_output(col, nil, 5, col_identifier)
117
- when :datetime
118
- "<%= datetime_field_localized(f, :#{col.to_s}, #{singular}.#{col.to_s}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
119
- when :date
120
- "<%= date_field_localized(f, :#{col.to_s}, #{singular}.#{col.to_s}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
121
- when :time
122
- "<%= time_field_localized(f, :#{col.to_s}, #{singular}.#{col.to_s}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
123
- when :boolean
124
- " " +
125
- " <span>#{col.to_s.humanize}</span>" +
126
- " <%= f.radio_button(:#{col.to_s}, '0', checked: #{singular}.#{col.to_s} ? '' : 'checked') %>\n" +
127
- " <%= f.label(:#{col.to_s}, value: 'No', for: '#{singular}_#{col.to_s}_0') %>\n" +
128
- " <%= f.radio_button(:#{col.to_s}, '1', checked: #{singular}.#{col.to_s} ? 'checked' : '') %>\n" +
129
- " <%= f.label(:#{col.to_s}, value: 'Yes', for: '#{singular}_#{col.to_s}_1') %>\n" +
130
- ""
131
- when :enum
132
- enum_type = eval("#{singular_class}.columns.select{|x| x.name == '#{col.to_s}'}[0].sql_type")
133
- "<%= f.collection_select(:#{col.to_s}, enum_to_collection_select( #{singular_class}.defined_enums['#{enum_type}']), :key, :value, {selected: @#{singular}.#{col.to_s} }, class: 'form-control') %>
134
- <label class='small form-text text-muted'>#{col.to_s.humanize}</label>"
135
143
  end
136
- end
137
-
138
- if (type == :integer) && col.to_s.ends_with?("_id")
139
- field_error_name = col.to_s.gsub("_id","")
140
- else
141
- field_error_name = col.to_s
142
- end
143
- "<span class='<%= \"alert-danger\" if #{singular}.errors.details.keys.include?(:#{field_error_name}) %>' #{ 'style="display: inherit;"'} >" + field_result + "</span>"
144
- }.join("<br />\n") + "</div>"
144
+
145
+ if (type == :integer) && col.to_s.ends_with?("_id")
146
+ field_error_name = col.to_s.gsub("_id","")
147
+ else
148
+ field_error_name = col
149
+ end
150
+
151
+ add_spaces_each_line( "\n <span class='<%= \"alert-danger\" if #{singular}.errors.details.keys.include?(:#{field_error_name}) %>' #{ 'style="display: inherit;"'} >\n" +
152
+ add_spaces_each_line(field_result + "\n<label class='small form-text text-muted'>#{col.to_s.humanize}</label>", 4) +
153
+ "\n </span>\n <br />", 2)
154
+
155
+ }.join("") + "\n </div>"
145
156
  }.join("\n")
146
157
  return result
147
158
  end
@@ -161,20 +172,20 @@ module HotGlue
161
172
  singular = args[0][:singular]
162
173
  perc_width = args[0][:perc_width]
163
174
  layout = args[0][:layout]
175
+ col_identifier = args[0][:col_identifier] || (layout == "bootstrap" ? "col-md-2" : "scaffold-cell")
176
+
164
177
 
165
178
  columns_count = layout_columns.count + 1
166
179
  perc_width = (perc_width).floor
167
180
 
168
181
  if layout == "bootstrap"
169
- col_identifer = "col-md-2"
170
182
  style_with_flex_basis = ""
171
183
  else
172
184
  style_with_flex_basis = " style='flex-basis: #{perc_width}%'"
173
- col_identifer = "scaffold-cell"
174
185
  end
175
186
 
176
187
  result = layout_columns.map{ |column|
177
- "<div class='#{col_identifer}'#{style_with_flex_basis}>" +
188
+ "<div class='#{col_identifier}'#{style_with_flex_basis}>" +
178
189
 
179
190
 
180
191
  column.map { |col|
@@ -185,7 +196,7 @@ module HotGlue
185
196
  case type
186
197
  when :integer
187
198
  # look for a belongs_to on this object
188
- if col.to_s.ends_with?("_id")
199
+ if col.ends_with?("_id")
189
200
 
190
201
  assoc_name = col.to_s.gsub("_id","")
191
202
 
@@ -243,7 +254,7 @@ module HotGlue
243
254
  <% end %>
244
255
 
245
256
  " when :enum
246
- enum_type = eval("#{singular_class}.columns.select{|x| x.name == '#{col.to_s}'}[0].sql_type")
257
+ enum_type = eval("#{singular_class}.columns.select{|x| x.name == '#{col}'}[0].sql_type")
247
258
 
248
259
  "
249
260
  <% if #{singular}.#{col}.nil? %>