brick 1.0.149 → 1.0.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91e6b3d87c423a90e6e6cf62a07235e185373d9bb60990579a13ccea83c6a645
4
- data.tar.gz: 8670e080c676eb7c5be3bb62b7ce4e7a310e8d30c98c3d189d513bd9e06a2af3
3
+ metadata.gz: 1d8abfeb02b561a0ac8214de3c4791992947cab9f288f9f57c816a883dc4592a
4
+ data.tar.gz: 1ec0f9d11eea9b1741e454ac04aa2c51380a0d9676f4e84a5de2419d3ef751bd
5
5
  SHA512:
6
- metadata.gz: 58ff4070f313c577b027f2c83babb99c2aeecaf0cfd05edbed89ed6e5a32485a9bdc8849e303d9eb16fa6f5824beb66e4dbf282843bc4e2b1a00c7ec13e0616a
7
- data.tar.gz: 20cd0a6b43f267a653923a86ded57b041cbe49adbd1e239236faac18415eab0e8515490e0828dcc67f4d7e4f809efae9ff7249a1ab5d9a9626a8a24dced8d2d9
6
+ metadata.gz: 758e2ab6e10589689abdb77df64731e3df2fff341998e8f815bd5f180a73df89fb1282155a9520cc43102a49b1f7283114c02146329161e2324fc2fa79c6048e
7
+ data.tar.gz: 9a77d3d4318943225427c59e676c4a067c95a22351eaea88ed14bbc6da60ee834498117704bc0fe1dd493f6e10ab65a27db4bff3b060440f4e7dfaf3b31ad184
@@ -1528,12 +1528,12 @@ class Object
1528
1528
  # end
1529
1529
  end
1530
1530
 
1531
- # Enable Turbo Stream if possible -- equivalent of: broadcasts_to ->(comment) { :comments }
1532
- if Object.const_defined?(:ApplicationCable) && Object.const_defined?(:Turbo) && Turbo.const_defined?(:Broadcastable) && respond_to?(:broadcasts_to)
1533
- relation[:broadcasts] = true
1534
- self.broadcasts_to ->(model) { (model&.class&.name || chosen_name).underscore.pluralize.to_sym }
1535
- code << " broadcasts_to ->(#{chosen_name}) { #{chosen_name}&.class&.name&.underscore&.pluralize&.to_sym }\n"
1536
- end
1531
+ # # %%% Enable Turbo Stream if possible -- equivalent of: broadcasts_to ->(comment) { :comments }
1532
+ # if Object.const_defined?(:ApplicationCable) && Object.const_defined?(:Turbo) && Turbo.const_defined?(:Broadcastable) && respond_to?(:broadcasts_to)
1533
+ # relation[:broadcasts] = true
1534
+ # self.broadcasts_to ->(model) { (model&.class&.name || chosen_name).underscore.pluralize.to_sym }
1535
+ # code << " broadcasts_to ->(#{chosen_name}) { #{chosen_name}&.class&.name&.underscore&.pluralize&.to_sym }\n"
1536
+ # end
1537
1537
  end # class definition
1538
1538
  # Having this separate -- will this now work out better?
1539
1539
  built_model.class_exec do
@@ -2155,13 +2155,16 @@ class Object
2155
2155
  ::Brick.set_db_schema(params)
2156
2156
  if request.format == :csv # Importing CSV?
2157
2157
  require 'csv'
2158
+
2158
2159
  # See if internally it's likely a TSV file (tab-separated)
2159
- tab_counts = []
2160
- 5.times { tab_counts << request.body.readline.count("\t") unless request.body.eof? }
2160
+ likely_separator = Hash.new { |h, k| h[k] = 0 }
2161
+ request.body.readline # Expect first row to have column headers
2162
+ 5.times { ::Brick._find_csv_separator(request.body, likely_separator) unless request.body.eof? }
2161
2163
  request.body.rewind
2162
- separator = "\t" if tab_counts.length > 0 && tab_counts.uniq.length == 1 && tab_counts.first > 0
2163
- result = model.df_import(CSV.parse(request.body, { col_sep: separator || :auto }), model.brick_import_template)
2164
- # render inline: exported_csv, content_type: request.format
2164
+ separator = "\t" if likely_separator["\t"] > likely_separator[',']
2165
+
2166
+ result = model.df_import(CSV.parse(request.body, **{ col_sep: separator || :auto }), model.brick_import_template)
2167
+ render inline: result.to_json, content_type: request.format
2165
2168
  return
2166
2169
  # elsif request.format == :js # Asking for JSON?
2167
2170
  # render inline: model.df_export(true).to_json, content_type: request.format
@@ -2238,14 +2241,9 @@ class Object
2238
2241
 
2239
2242
  if is_need_params
2240
2243
  code << " def #{params_name}\n"
2241
- permits = model.columns_hash.keys.map(&:to_sym)
2242
- permits_txt = permits.map(&:inspect) +
2243
- model.reflect_on_all_associations.select { |assoc| assoc.macro == :has_many && assoc.options[:through] }.map do |assoc|
2244
- permits << { "#{assoc.name.to_s.singularize}_ids".to_sym => [] }
2245
- "#{assoc.name.to_s.singularize}_ids: []"
2246
- end
2244
+ permits_txt = self._brick_find_permits(model, (permits = model.columns_hash.keys.map(&:to_sym)))
2247
2245
  code << " params.require(:#{require_name = model.name.underscore.tr('/', '_')
2248
- }).permit(#{permits_txt.join(', ')})\n"
2246
+ }).permit(#{permits_txt.map(&:inspect).join(', ')})\n"
2249
2247
  code << " end\n"
2250
2248
  self.define_method(params_name) do
2251
2249
  params.require(require_name.to_sym).permit(permits)
@@ -2259,6 +2257,101 @@ class Object
2259
2257
  [built_controller, code]
2260
2258
  end
2261
2259
 
2260
+ def _brick_find_permits(model, current_permits, done_permits = [])
2261
+ unless done_permits.include?(self)
2262
+ done_permits << self
2263
+ model.reflect_on_all_associations.select { |assoc| assoc.macro == :has_many }.each_with_object([]) do |assoc, s|
2264
+ if assoc.options[:through]
2265
+ current_permits << { "#{assoc.name.to_s.singularize}_ids".to_sym => [] }
2266
+ s << "#{assoc.name.to_s.singularize}_ids: []"
2267
+ elsif assoc.active_record.instance_methods.include?(:"#{assoc.name}_attributes=")
2268
+ # Support nested attributes which use the friendly_id gem
2269
+ self._brick_nested_friendly_id if Object.const_defined?('FriendlyId') &&
2270
+ assoc.klass.instance_variable_get(:@friendly_id_config)
2271
+ new_attrib_text = self._brick_find_permits(assoc.klass, (new_permits = assoc.klass.columns_hash.keys.map(&:to_sym)), done_permits)
2272
+ new_permits << :_destroy
2273
+ current_permits << { "#{assoc.name}_attributes".to_sym => new_permits }
2274
+ s << "#{assoc.name}_attributes: #{new_attrib_text}"
2275
+ end
2276
+ end
2277
+ end
2278
+ current_permits
2279
+ end
2280
+
2281
+ def _brick_nested_friendly_id
2282
+ unless @_brick_nested_friendly_id
2283
+ ::ActiveRecord::Base.class_exec do
2284
+ if private_instance_methods.include?(:assign_nested_attributes_for_collection_association)
2285
+ alias _brick_anafca assign_nested_attributes_for_collection_association
2286
+ def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
2287
+ association = association(association_name)
2288
+ slug_column = association.klass.instance_variable_get(:@friendly_id_config)&.slug_column
2289
+ return _brick_anafca unless slug_column
2290
+
2291
+ # Here is the FriendlyId version of #assign_nested_attributes_for_collection_association
2292
+ options = nested_attributes_options[association_name]
2293
+ attributes_collection = attributes_collection.to_h if attributes_collection.respond_to?(:permitted?)
2294
+
2295
+ unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
2296
+ raise ArgumentError, "Hash or Array expected for attribute `#{association_name}`, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
2297
+ end
2298
+
2299
+ check_record_limit!(options[:limit], attributes_collection)
2300
+
2301
+ if attributes_collection.is_a? Hash
2302
+ keys = attributes_collection.keys
2303
+ attributes_collection = if keys.include?("id") || keys.include?(:id)
2304
+ [attributes_collection]
2305
+ else
2306
+ attributes_collection.values
2307
+ end
2308
+ end
2309
+ existing_records = if association.loaded?
2310
+ association.target
2311
+ else
2312
+ attribute_ids = attributes_collection.filter_map { |a| a["id"] || a[:id] }
2313
+ if attribute_ids.empty?
2314
+ []
2315
+ else # Implement the same logic as "friendly" scope
2316
+ association.scope.where(association.klass.primary_key => attribute_ids)
2317
+ .or(association.scope.where(slug_column => attribute_ids))
2318
+ end
2319
+ end
2320
+ attributes_collection.each do |attributes|
2321
+ attributes = attributes.to_h if attributes.respond_to?(:permitted?)
2322
+ attributes = attributes.with_indifferent_access
2323
+ if attributes["id"].blank? && attributes[slug_column].blank?
2324
+ unless reject_new_record?(association_name, attributes)
2325
+ association.reader.build(attributes.except(*::ActiveRecord::Base::UNASSIGNABLE_KEYS))
2326
+ end
2327
+ elsif (attr_id_str = attributes["id"].to_s) &&
2328
+ (existing_record = existing_records.detect { |record| record.id.to_s == attr_id_str ||
2329
+ record.send(slug_column).to_s == attr_id_str })
2330
+ unless call_reject_if(association_name, attributes)
2331
+ # Make sure we are operating on the actual object which is in the association's
2332
+ # proxy_target array (either by finding it, or adding it if not found)
2333
+ # Take into account that the proxy_target may have changed due to callbacks
2334
+ target_record = association.target.detect { |record| record.id.to_s == attr_id_str ||
2335
+ record.send(slug_column).to_s == attr_id_str }
2336
+ if target_record
2337
+ existing_record = target_record
2338
+ else
2339
+ association.add_to_target(existing_record, skip_callbacks: true)
2340
+ end
2341
+
2342
+ assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
2343
+ end
2344
+ else
2345
+ raise_nested_attributes_record_not_found!(association_name, attributes["id"])
2346
+ end
2347
+ end
2348
+ end # anafca
2349
+ end
2350
+ end if ::ActiveRecord::QueryMethods.instance_methods.include?(:or)
2351
+ @_brick_nested_friendly_id = true
2352
+ end
2353
+ end
2354
+
2262
2355
  def _brick_get_hm_assoc_name(relation, hm_assoc, source = nil)
2263
2356
  assoc_name, needs_class = if (relation[:hm_counts][hm_assoc[:inverse_table]]&.> 1) &&
2264
2357
  hm_assoc[:alternate_name] != (source || name.underscore)
@@ -263,11 +263,11 @@ function linkSchemas() {
263
263
 
264
264
  # After we're initialized and before running the rest of stuff, put our configuration in place
265
265
  ActiveSupport.on_load(:after_initialize) do |app|
266
- assets_path = File.expand_path("#{__dir__}/../../../../vendor/assets")
267
- if (app_config = app.config).respond_to?(:assets)
268
- (app_config.assets.precompile ||= []) << "#{assets_path}/images/brick_erd.png"
269
- (app.config.assets.paths ||= []) << assets_path
270
- end
266
+ # assets_path = File.expand_path("#{__dir__}/../../../../vendor/assets")
267
+ # if (app_config = app.config).respond_to?(:assets)
268
+ # (app_config.assets.precompile ||= []) << "#{assets_path}/images/brick_erd.png"
269
+ # (app.config.assets.paths ||= []) << assets_path
270
+ # end
271
271
 
272
272
  # Treat ActiveStorage::Blob metadata as JSON
273
273
  if ::Brick.config.table_name_prefixes.fetch('active_storage_', nil) == 'ActiveStorage' &&
@@ -813,7 +813,7 @@ h1, h3 {
813
813
  margin-bottom: 0;
814
814
  }
815
815
  #imgErd {
816
- background-image:url(/assets/brick_erd.png);
816
+ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE0AAABNCAMAAADU1xmCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAARxaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDoxN0U3OEI3RjAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDoxN0U3OEI4MDAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDoxN0U3OEI4MjAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDoxN0U3OEI4MTAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3M8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+ChMBcXgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAL9UExURUdwTDRRc1EVG6ioqFJSUmJiYn+AgURWa2uEkauorszGwmtrawonUKzY7DMRIlFTVWV9m4qKiwaN0G1raJSQiJjV7jWh2HmizPLs6CaV0QohSmdoaVdXWLWsomFdYmIgD4WCfQWa2WIoFUxylldpekeRuGtrajhztIuLizV3qc3DvThDVEyFs31+fiRViVRNViVWjwsvWxIzXxZEekeL1FZIVVRdeEZrk359fj52ppubm3l6e4qbqJOTlBlGfM3k3Nzc3K6lnk9RWaenp0FjikGDyJGRkWJiYk2L0Li4uJubnH5+flFbeNPT02tpac3NzVBGJkCCyMvLy9LS0oxETk2U3tLS0tXV1cPDw+Xl5amDftbX19na2uLj4+jo6dzd3OXl511dXd/g31paWlZXV9TU1HBwcOvr687OzdDQ0u/u7fTx79PSzcrJx6KiooWFhujn5NvW05WUk7S1t3R1d7y9vcLCv37J68vMzVJTVOLY1gMiSpmamnt7e7K6zHq+43LQ9Vyez+Pf3LGyscXGybzD1sXDw46v02vI8I+Pj7vEtNvIx7q4ubnZ54a3it3f5s+8vGS/6L6trK+6qICs1H+33cXc6KiuwAOr48fN20ee0Fao0lyz4W6s1qyrrKKlt3XdkoqnyyFoqzuTy6ixosuVeobA4YHNl8TOv3/Ck9bc4I3P7Uqq3tDIxz2FwzN/vF+VxdDe59mIfU+OxJmovxl+wX7S9WjbhovW9jihyKGalIq31uNyY36exJCatJONhTm36nKj0B2q4Mqxsae2zc/U3tvf1cqKa7zAyJS4npqyyTh2tUhMT1drj5ixtN98cEfC8U2Y5vf39355cSN0s4mDfKaomlrG8b2cmcFvaGx/m2CeZge68HG64YCNntSgoVHUdJzKnIHIh6c+BalVVaPM5qrG2CZZkyaHH3WRtYrdn5nH2rxoP22+gN1VQTyxW1aXl0iO2GaxtFuzaCCAQyXSWDOKlDZwkxIINVZPP52Io3uldtIoC1uGVxmzRP6PHn8AAADVdFJOUwAmEf6t/v4EAQVR/oT+Hl4U/v1bR/7+Kf7+a/76Q4Y2Wf1b4j71sXm0y2hF/bBwbtXN/fyGl8Sxiu382Preqfzia9iIkdP51/Povnineu+9n6H7ov5ksLfYy/7////////+/////////////////////v/////////////////////////////////////////////////////////////////////////////+/////////////////////////////////////////////////////r5xM8kAAA0qSURBVFjDpZh3WFNnG8YDMZOiLEFEsVhn1Vq1Vq1abWv3br+dc5IQsklCSEiIyAoJyAhb9h4ishVQcCAIOLC4UBFxr7bu0X6dX6/vec8JikIptecPVrh+576f5z3vez+HQmGyKBSK28eT4SsL/fiXLiaFwmD/E5NzPmU7wG8s5l/DOXy8+vhxLg8TcN5/yw0JZPwV2GoJH+fjPI7UHBWV/8HzwGIynlkgm+vv788RiURSs06bT6WuJAQynlEgO+JaUzoWhGAWE1X1mkqlmYUEMp5JIBs7ejYz3L4iyN+gy1epVMGvaYI1K5faIIF/nsfuPDr325LMo5XpvCCFThUMrHccY2L85j2TQHZna11kZFGd19lo+4oI/yiqJiYmxtGP7kdf/gwC2bLWuix1RWTX7uzMo+PTI4KkJo0fXPSQkBDxDOc/KZBtaK3P4uLqrPXri+rcz4YjgbpgegidHhIgDhC/6/mnBLLNVTWdclzdmbYTeAMClVS6OCAgQGxnZ0cbM4dBPDKjoh2oqo309ZV3ppWV7UTAur1nw+MrIhRaRzsPsdiDRqN5v+lpO0oc0OrrirLkiWGVZVYeIXBLRFBUsNiH5kHz9vHxeZMxOhxb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);
817
817
  background-size: 100% 100%;
818
818
  width: 2.2em;
819
819
  height: 2.2em;
@@ -1241,7 +1241,9 @@ erDiagram
1241
1241
  btnImport.style.display = droppedTSV.length > 0 ? \"block\" : \"none\";
1242
1242
  });
1243
1243
  btnImport.addEventListener(\"click\", function () {
1244
- fetch(changeout(<%= #{path_obj_name}_path(-1, format: :csv).inspect.html_safe %>, \"_brick_schema\", brickSchema), {
1244
+ var patchPath = <%= #{path_obj_name}_path(-1, format: :csv).inspect.html_safe %>;
1245
+ if (brickSchema) patchPath = changeout(patchPath, \"_brick_schema\", brickSchema);
1246
+ fetch(patchPath, {
1245
1247
  method: \"PATCH\",
1246
1248
  headers: { \"Content-Type\": \"text/tab-separated-values\" },
1247
1249
  body: droppedTSV
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 149
8
+ TINY = 151
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
@@ -742,6 +742,28 @@ In config/initializers/brick.rb appropriate entries would look something like:
742
742
  @double_underscore_applied = true
743
743
  end
744
744
  end
745
+
746
+ def _find_csv_separator(stream, likely_separator)
747
+ line = nil
748
+ last_char = nil
749
+ in_quotes = false
750
+ ret = +''
751
+ while true
752
+ (line = stream.readline).each_char do |ch|
753
+ likely_separator[ch] += 2 if !in_quotes && last_char == '"' && ch != "\n"
754
+ if ch == '"'
755
+ in_quotes = !in_quotes
756
+ likely_separator[last_char] += 2 if in_quotes && last_char != "\n"
757
+ end
758
+ last_char = ch
759
+ end
760
+ ret << line
761
+ break if !in_quotes || stream.eof?
762
+ end
763
+ likely_separator[line[0]] += 1
764
+ likely_separator[line[-2]] += 1
765
+ ret
766
+ end
745
767
  end
746
768
 
747
769
  module RouteSet
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.149
4
+ version: 1.0.151
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-06-01 00:00:00.000000000 Z
11
+ date: 2023-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord