brick 1.0.158 → 1.0.160

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 326ec09b1c28cf7c54e54bae9ea6ceed7d7e476a177be0a41af14e04f7cc3d11
4
- data.tar.gz: 0507c22a2acf86c58737ecfedeb1a1f5ed6979b5263b28c6d6e77b0e9500ab7c
3
+ metadata.gz: 735ad34b99ba52ae2575c786fdee6c359c5c53e6d2edf53b19bbb5d1f02869ec
4
+ data.tar.gz: c603e9adebe13192e4be8724b51d563a6b39f89b15c61fab253debb9fc959a66
5
5
  SHA512:
6
- metadata.gz: d6803593a5c3e17ef40005c405017ed4e7519024ca172a077ad377c201a7b2e2caf2a8b4bc5a0ef63f091124a44199ffd3b386db7d6b5d51352f2e3327537d81
7
- data.tar.gz: 486b0a15422b0d3150b575c8d19c24cc3434e3fd8f35335d2e490e1e69e423995a2032de913def73b4f4df0e2789c6f4af7d61930db5cc144d0a0cb76be3ebdc
6
+ metadata.gz: 14b5a64e366d218ac78bb3ec26370cddcdb506ee292974321a76331a40d272a33ce49b9cb4911314a7e33835bf44255dda73c04449062e159b499e2e0d88c61f
7
+ data.tar.gz: cfa821c073296681b4b49e0d58538e076ac50ae1ea65b2df6ea8af1c92477842ee737c3d5950d803ce45f52daf48fca065f28bf6cc6a5e6518c408a64305ada6
@@ -97,11 +97,13 @@ if Object.const_defined?('ActionPack') && !ActionPack.respond_to?(:version)
97
97
  end
98
98
  end
99
99
  end
100
- require 'action_view' # Needed for Rails <= 4.0
101
- if Object.const_defined?('ActionView') && !ActionView.respond_to?(:version)
102
- module ActionView
103
- def self.version
104
- ActionPack.version
100
+ if Bundler.locked_gems&.dependencies.key?('action_view')
101
+ require 'action_view' # Needed for Rails <= 4.0
102
+ if Object.const_defined?('ActionView') && !ActionView.respond_to?(:version)
103
+ module ActionView
104
+ def self.version
105
+ ActionPack.version
106
+ end
105
107
  end
106
108
  end
107
109
  end
@@ -30,14 +30,14 @@
30
30
 
31
31
  # Drag something like HierModel#name onto the rows and have it automatically add five columns -- where type=zone / where type = section / etc
32
32
 
33
- # Support for Postgres / MySQL enums (add enum to model, use model enums to make a drop-down in the UI)
34
-
35
- # Currently quadrupling up routes
36
-
37
33
  # Modal pop-up things for editing large text / date ranges / hierarchies of data
38
34
 
39
35
  # For recognised self-references, have the show page display all related objects up to the parent (or the start of a circular reference)
40
36
 
37
+ # When creating or updating an object through an auto-generated controller, it always goes to an auto-generated view template even if the user has supplied their own index.html.erb (or similar) view template
38
+
39
+ # Upon creation of a new object, when going to the index page, highlight this new object and scroll it into view (likely to the very bottom of everything, although might be sorted differently)
40
+
41
41
  # ==========================================================
42
42
  # Dynamically create model or controller classes when needed
43
43
  # ==========================================================
@@ -2199,7 +2199,8 @@ class Object
2199
2199
  render json: { result: ::Brick.unexclude_column(table_name, col) }
2200
2200
  else
2201
2201
  @_lookup_context.instance_variable_set("@#{singular_table_name}".to_sym,
2202
- model.send(:create, send(params_name_sym)))
2202
+ (created_obj = model.send(:create, send(params_name_sym))))
2203
+ # %%% Surface any errors to the user in a flash message
2203
2204
  @_lookup_context.instance_variable_set(:@_brick_model, model)
2204
2205
  index
2205
2206
  render :index
@@ -1667,89 +1667,9 @@ end
1667
1667
  end
1668
1668
  %>
1669
1669
  <br><br>
1670
- <%= form_for(obj.becomes(#{model_name}), options) do |f| %>
1671
- <table class=\"shadow\">
1672
- <% has_fields = false
1673
- # If it's a new record, set any default polymorphic types
1674
- bts.each do |_k, v|
1675
- if v[2]
1676
- @#{obj_name}.send(\"#\{model.brick_foreign_type(v.first)}=\", v[1].first&.first&.name)
1677
- end
1678
- end if @#{obj_name}.new_record?
1679
- rtans = #{model_name}.rich_text_association_names if #{model_name}.respond_to?(:rich_text_association_names)
1680
- (#{model_name}.column_names + (rtans || [])).each do |k|
1681
- next if (#{(pk.map(&:to_s) || []).inspect}.include?(k) && !bts.key?(k)) ||
1682
- ::Brick.config.metadata_columns.include?(k)
1683
-
1684
- col = #{model_name}.columns_hash[k]
1685
- if !col && rtans&.include?(k)
1686
- k = k[10..-1] if k.start_with?('rich_text_')
1687
- col = (rt_col ||= ActiveRecord::ConnectionAdapters::Column.new(
1688
- '', nil, ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: 'varchar', type: :text)
1689
- )
1690
- )
1691
- end
1692
- val = @#{obj_name}.attributes[k] %>
1693
- <tr>
1694
- <th class=\"show-field\"<%= \" title=\\\"#\{col&.comment}\\\"\".html_safe if col&.respond_to?(:comment) && !col&.comment.blank? %>>
1695
- <% has_fields = true
1696
- if (bt = bts[k])
1697
- # Add a final member in this array with descriptive options to be used in <select> drop-downs
1698
- bt_name = bt[1].map { |x| x.first.name }.join('/')
1699
- # %%% Only do this if the user has permissions to edit this bt field
1700
- if bt[2] # Polymorphic?
1701
- poly_class_name = orig_poly_name = @#{obj_name}.send(model.brick_foreign_type(bt.first))
1702
- bt_pair = nil
1703
- loop do
1704
- bt_pair = bt[1].find { |pair| pair.first.name == poly_class_name }
1705
- # Accommodate any valid STI by going up the chain of inheritance
1706
- break unless bt_pair.nil? && poly_class_name = ::Brick.existing_stis[poly_class_name]
1707
- end
1708
- puts \"*** Might be missing an STI class called #\{orig_poly_name\} whose base class should have this:
1709
- *** has_many :#{table_name}, as: :#\{bt.first\}
1710
- *** Can probably auto-configure everything using these lines in an initialiser:
1711
- *** Brick.sti_namespace_prefixes = { '::#\{orig_poly_name\}' => 'SomeParentModel' }
1712
- *** Brick.polymorphics = { '#{table_name}.#\{bt.first\}' => ['SomeParentModel'] }\" if bt_pair.nil?
1713
- # descrips = @_brick_bt_descrip[bt.first][bt_class]
1714
- poly_id = @#{obj_name}.send(\"#\{bt.first\}_id\")
1715
- # bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
1716
- end
1717
- bt_pair ||= bt[1].first # If there's no polymorphism (or polymorphism status is unknown), just get the first one
1718
- bt_class = bt_pair&.first
1719
- if bt.length < 4
1720
- bt << (option_detail = [[\"(No #\{bt_name\} chosen)\", '^^^brick_NULL^^^']])
1721
- # %%% Accommodate composite keys for obj.pk at the end here
1722
- collection, descrip_cols = bt_class&.order(Arel.sql(\"#\{bt_class.table_name}.#\{obj_pk = bt_class.primary_key}\"))&.brick_list
1723
- collection&.brick_(:each) do |obj|
1724
- option_detail << [
1725
- obj.brick_descrip(
1726
- descrip_cols&.first&.map { |col2| obj.send(col2.last) },
1727
- obj_pk
1728
- ), obj.send(obj_pk)
1729
- ]
1730
- end
1731
- end %>
1732
- BT <%= bt_class&.bt_link(bt.first) || orig_poly_name %>
1733
- <% else %>
1734
- <%= #{model_name}.human_attribute_name(k, { default: k }) %>
1735
- <% end %>
1736
- </th>
1737
- <td>
1738
- <%= f.brick_field(k, html_options = {}, val, col, bt, bt_class, bt_name, bt_pair) %>
1739
- </td>
1740
- </tr>
1741
- <% end
1742
- if has_fields %>
1743
- <tr><td colspan=\"2\"><%= f.submit({ class: 'update' }) %></td></tr>
1744
- <% else %>
1745
- <tr><td colspan=\"2\">(No displayable fields)</td></tr>
1746
- <% end %>
1747
- </table>#{
1748
- "<%= begin
1749
- ::Brick::Rails.display_binary(obj&.blob&.download, 500_000)&.html_safe
1750
- rescue
1751
- end %>" if model_name == 'ActiveStorage::Attachment'}
1752
- <% end %>
1670
+
1671
+ <%= # Write out the mega-form
1672
+ brick_form_for(obj, options, #{model_name}, bts, #{pk.inspect}) %>
1753
1673
 
1754
1674
  #{unless args.first == 'new'
1755
1675
  # Was: confirm_are_you_sure = ActionView.version < ::Gem::Version.new('7.0') ? "data: { confirm: 'Delete #\{model_name} -- Are you sure?' }" : "form: { data: { turbo_confirm: 'Delete #\{model_name} -- Are you sure?' } }"
@@ -67,9 +67,14 @@ module Brick::Rails::FormBuilder
67
67
  when :boolean
68
68
  out << self.check_box(method.to_sym)
69
69
  when :integer, :decimal, :float
70
- digit_pattern = col_type == :integer ? '\d*' : '\d*(?:\.\d*|)'
71
- # Used to do this for float / decimal: self.number_field method.to_sym
72
- out << self.text_field(method.to_sym, { pattern: digit_pattern, class: 'check-validity' })
70
+ if model.respond_to?(:attribute_types) && (enum_type = model.attribute_types[method]).is_a?(ActiveRecord::Enum::EnumType)
71
+ opts = enum_type.send(:mapping)&.each_with_object([]) { |v, s| s << [v.first, v.first] } || []
72
+ out << self.select(method.to_sym, [["(No #{method} chosen)", '^^^brick_NULL^^^']] + opts, { value: val || '^^^brick_NULL^^^' }, options)
73
+ else
74
+ digit_pattern = col_type == :integer ? '\d*' : '\d*(?:\.\d*|)'
75
+ # Used to do this for float / decimal: self.number_field method.to_sym
76
+ out << self.text_field(method.to_sym, { pattern: digit_pattern, class: 'check-validity' })
77
+ end
73
78
  when *DT_PICKERS.keys
74
79
  template.instance_variable_set(:@_date_fields_present, true)
75
80
  out << self.text_field(method.to_sym, { class: DT_PICKERS[col_type] })
@@ -203,6 +203,100 @@ module Brick::Rails::FormTags
203
203
  out.html_safe
204
204
  end # brick_grid
205
205
 
206
+ # Our mega show/new/update form
207
+ def brick_form_for(obj, options = {}, model = obj.class, bts = {}, pk = (obj.class.primary_key || []))
208
+ pk = [pk] unless pk.is_a?(Array)
209
+ pk.map!(&:to_s)
210
+ form_for(obj.becomes(model), options) do |f|
211
+ out = +'<table class="shadow">'
212
+ has_fields = false
213
+ # If it's a new record, set any default polymorphic types
214
+ bts&.each do |_k, v|
215
+ if v[2]
216
+ obj.send("#{model.brick_foreign_type(v.first)}=", v[1].first&.first&.name)
217
+ end
218
+ end if obj.new_record?
219
+ rtans = model.rich_text_association_names if model.respond_to?(:rich_text_association_names)
220
+ (model.column_names + (rtans || [])).each do |k|
221
+ next if (pk.include?(k) && !bts.key?(k)) ||
222
+ ::Brick.config.metadata_columns.include?(k)
223
+
224
+ col = model.columns_hash[k]
225
+ if !col && rtans&.include?(k)
226
+ k = k[10..-1] if k.start_with?('rich_text_')
227
+ col = (rt_col ||= ActiveRecord::ConnectionAdapters::Column.new(
228
+ '', nil, ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: 'varchar', type: :text)
229
+ )
230
+ )
231
+ end
232
+ val = obj.attributes[k]
233
+ out << "
234
+ <tr>
235
+ <th class=\"show-field\"#{" title=\"#{col&.comment}\"".html_safe if col&.respond_to?(:comment) && !col&.comment.blank?}>"
236
+ has_fields = true
237
+ if (bt = bts[k])
238
+ # Add a final member in this array with descriptive options to be used in <select> drop-downs
239
+ bt_name = bt[1].map { |x| x.first.name }.join('/')
240
+ # %%% Only do this if the user has permissions to edit this bt field
241
+ if bt[2] # Polymorphic?
242
+ poly_class_name = orig_poly_name = obj.send(model.brick_foreign_type(bt.first))
243
+ bt_pair = nil
244
+ loop do
245
+ bt_pair = bt[1].find { |pair| pair.first.name == poly_class_name }
246
+ # Accommodate any valid STI by going up the chain of inheritance
247
+ break unless bt_pair.nil? && poly_class_name = ::Brick.existing_stis[poly_class_name]
248
+ end
249
+ puts "*** Might be missing an STI class called #{orig_poly_name} whose base class should have this:
250
+ *** has_many :#{table_name}, as: :#{bt.first}
251
+ *** Can probably auto-configure everything using these lines in an initialiser:
252
+ *** Brick.sti_namespace_prefixes = { '::#{orig_poly_name}' => 'SomeParentModel' }
253
+ *** Brick.polymorphics = { '#{table_name}.#{bt.first}' => ['SomeParentModel'] }" if bt_pair.nil?
254
+ # descrips = @_brick_bt_descrip[bt.first][bt_class]
255
+ poly_id = obj.send("#{bt.first}_id")
256
+ # bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
257
+ end
258
+ bt_pair ||= bt[1].first # If there's no polymorphism (or polymorphism status is unknown), just get the first one
259
+ bt_class = bt_pair&.first
260
+ if bt.length < 4
261
+ bt << (option_detail = [["(No #{bt_name} chosen)", '^^^brick_NULL^^^']])
262
+ # %%% Accommodate composite keys for obj.pk at the end here
263
+ collection, descrip_cols = bt_class&.order(Arel.sql("#{bt_class.table_name}.#{obj_pk = bt_class.primary_key}"))&.brick_list
264
+ collection&.brick_(:each) do |obj|
265
+ option_detail << [
266
+ obj.brick_descrip(
267
+ descrip_cols&.first&.map { |col2| obj.send(col2.last) },
268
+ obj_pk
269
+ ), obj.send(obj_pk)
270
+ ]
271
+ end
272
+ end
273
+ out << "BT #{bt_class&.bt_link(bt.first) || orig_poly_name}"
274
+ else
275
+ out << model.human_attribute_name(k, { default: k })
276
+ end
277
+ out << "
278
+ </th>
279
+ <td>
280
+ #{f.brick_field(k, html_options = {}, val, col, bt, bt_class, bt_name, bt_pair)}
281
+ </td>
282
+ </tr>"
283
+ end
284
+ if has_fields
285
+ out << "<tr><td colspan=\"2\">#{f.submit({ class: 'update' })}</td></tr>"
286
+ else
287
+ out << '<tr><td colspan="2">(No displayable fields)</td></tr>'
288
+ end
289
+ out << '</table>'
290
+ if model.name == 'ActiveStorage::Attachment'
291
+ begin
292
+ out << ::Brick::Rails.display_binary(obj&.blob&.download, 500_000)&.html_safe
293
+ rescue
294
+ end
295
+ end
296
+ out.html_safe
297
+ end
298
+ end # brick_form_for
299
+
206
300
  def link_to_brick(*args, **kwargs)
207
301
  return unless ::Brick.config.mode == :on
208
302
 
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 158
8
+ TINY = 160
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
data/lib/brick.rb CHANGED
@@ -1112,20 +1112,22 @@ require 'active_record/relation'
1112
1112
  require 'active_record/relation/query_methods' if ActiveRecord.version < ::Gem::Version.new('5')
1113
1113
  require 'rails/railtie' if ActiveRecord.version < ::Gem::Version.new('4.2')
1114
1114
 
1115
- # Rake tasks
1116
- class Railtie < ::Rails::Railtie
1117
- Dir.glob("#{File.expand_path(__dir__)}/brick/tasks/**/*.rake").each { |task| load task }
1118
- end
1115
+ if Object.const_defined?('Rails')
1116
+ # Rake tasks
1117
+ class Railtie < ::Rails::Railtie
1118
+ Dir.glob("#{File.expand_path(__dir__)}/brick/tasks/**/*.rake").each { |task| load task }
1119
+ end
1119
1120
 
1120
- # Rails < 4.2 does not have env
1121
- module ::Rails
1122
- unless respond_to?(:env)
1123
- def self.env
1124
- @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
1125
- end
1121
+ # Rails < 4.2 does not have env
1122
+ module ::Rails
1123
+ unless respond_to?(:env)
1124
+ def self.env
1125
+ @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
1126
+ end
1126
1127
 
1127
- def self.env=(environment)
1128
- @_env = ActiveSupport::StringInquirer.new(environment)
1128
+ def self.env=(environment)
1129
+ @_env = ActiveSupport::StringInquirer.new(environment)
1130
+ end
1129
1131
  end
1130
1132
  end
1131
1133
  end
@@ -1,5 +1,7 @@
1
1
  module Brick
2
2
  module MigrationBuilder
3
+ include FancyGets
4
+
3
5
  # Many SQL types are the same as their migration data type name:
4
6
  # text, integer, bigint, date, boolean, decimal, float
5
7
  # These however are not:
@@ -8,7 +8,6 @@ require 'generators/brick/migration_builder'
8
8
  module Brick
9
9
  # Auto-generates migration files
10
10
  class MigrationsGenerator < ::Rails::Generators::Base
11
- include FancyGets
12
11
  include ::Brick::MigrationBuilder
13
12
 
14
13
  desc 'Auto-generates migration files for an existing database.'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brick
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.158
4
+ version: 1.0.160
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-29 00:00:00.000000000 Z
11
+ date: 2023-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord