brick 1.0.34 → 1.0.35

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: 9d1e2f8b6ff7ca3fa7fcd129c33de3dfe6e674b6da154b9a64e094c65a3a152a
4
- data.tar.gz: 30e39f62458a46854f56b2a6decbfe5ea42a4bb5325e81ed76f21400aae8e252
3
+ metadata.gz: 34a23d1057771acea1beb9ea1ea2ff3d27e5983084bcd47f4c87686af77328d5
4
+ data.tar.gz: 44aea0d5fb92a361913ba4a17ebca62cf5be9aca5585fa9785b7c388c2652cee
5
5
  SHA512:
6
- metadata.gz: 14c6bae09e34f53126e2003cbc7256c4b32f4a4219d42f1f7e94ca83211debf3704fa6c170cd6231d89e26eb168f282d1dea7eff7150ef1a013364aeb4eb65c3
7
- data.tar.gz: 7f33aa5c89be2e8401f4cda0ea6cecb6e01639934a2df1e7b00bd88d065bf3cc9b748bebb1691d51c1b04114fba3b1739a7820c7614f4eb84d52494bd4cc769e
6
+ metadata.gz: e9124cbd0db47816db2dcbf59a76adcc0d4dcaea8f4ad02ea9ee99aace025c8914a7871c78a4a703f4daeced7dbaec12d52fdf56b6bc131c4c855be931d4f838
7
+ data.tar.gz: 671d0333b9a89870db67cdec05306311475724d674aab494c794baa0648736c873ea2aade170bdbc51642b96e4fe76a19f568bf31e724bd513230e1a78c69521
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/version'
4
+
5
+ # ActiveRecord before 4.0 didn't have #version
6
+ unless ActiveRecord.respond_to?(:version)
7
+ module ActiveRecord
8
+ def self.version
9
+ ::Gem::Version.new(ActiveRecord::VERSION::STRING)
10
+ end
11
+ end
12
+ end
13
+
14
+ # In ActiveSupport older than 5.0, the duplicable? test tries to new up a BigDecimal,
15
+ # and Ruby 2.6 and later deprecates #new. This removes the warning from BigDecimal.
16
+ # This compatibility needs to be put into place in the application's "config/boot.rb"
17
+ # file by having the line "require 'brick/compatibility'" to be the last line in that
18
+ # file.
19
+ require 'bigdecimal'
20
+ if ::Gem::Version.new(RUBY_VERSION) >= ::Gem::Version.new('2.6') &&
21
+ ActiveRecord.version < ::Gem::Version.new('5.0')
22
+ def BigDecimal.new(*args, **kwargs)
23
+ BigDecimal(*args, **kwargs)
24
+ end
25
+ end
@@ -203,7 +203,9 @@ module ActiveRecord
203
203
  model_underscore = name.underscore
204
204
  assoc_name = CGI.escapeHTML(assoc_name.to_s)
205
205
  model_path = Rails.application.routes.url_helpers.send("#{model_underscore.tr('/', '_').pluralize}_path".to_sym)
206
- link = Class.new.extend(ActionView::Helpers::UrlHelper).link_to(name, model_path)
206
+ av_class = Class.new.extend(ActionView::Helpers::UrlHelper)
207
+ av_class.extend(ActionView::Helpers::TagHelper) if ActionView.version < ::Gem::Version.new('6.1')
208
+ link = av_class.link_to(name, model_path)
207
209
  model_underscore == assoc_name ? link : "#{assoc_name}-#{link}".html_safe
208
210
  end
209
211
 
@@ -409,7 +411,6 @@ module ActiveRecord
409
411
  hm_counts.each do |k, hm|
410
412
  associative = nil
411
413
  count_column = if hm.options[:through]
412
- # binding.pry if associatives[hm.name].nil?
413
414
  fk_col = (associative = associatives[hm.name]).foreign_key
414
415
  hm.foreign_key
415
416
  else
@@ -500,8 +501,9 @@ if ActiveSupport::Dependencies.respond_to?(:autoload_module!) # %%% Only works w
500
501
  alias _brick_autoload_module! autoload_module!
501
502
  def autoload_module!(*args)
502
503
  into, const_name, qualified_name, path_suffix = args
503
- base_class_name = ::Brick.config.sti_namespace_prefixes&.fetch("::#{into.name}::", nil)
504
- base_class_name = "::#{base_class_name}" unless base_class_name.start_with?('::')
504
+ if (base_class_name = ::Brick.config.sti_namespace_prefixes&.fetch("::#{into.name}::", nil))
505
+ base_class_name = "::#{base_class_name}" unless base_class_name.start_with?('::')
506
+ end
505
507
  if (base_class = base_class_name&.constantize)
506
508
  ::Brick.sti_models[qualified_name] = { base: base_class }
507
509
  # Build subclass and place it into the specially STI-namespaced module
@@ -777,9 +779,12 @@ class Object
777
779
  options = { through: through.to_sym }
778
780
  if relation[:fks].any? { |k, v| v[:assoc_name] == hmt_name }
779
781
  hmt_name = "#{hmt_name.singularize}_#{fk.first[:assoc_name]}"
780
- # binding.pry if relation[:fks].any? { |k, v| v[:assoc_name] == hmt_name }
781
- options[:class_name] = fk.first[:inverse_table].singularize.camelize
782
- options[:foreign_key] = fk.first[:fk].to_sym
782
+ # Was:
783
+ # options[:class_name] = fk.first[:inverse_table].singularize.camelize
784
+ # options[:foreign_key] = fk.first[:fk].to_sym
785
+ far_assoc = relations[fk.first[:inverse_table]][:fks].find { |_k, v| v[:assoc_name] == fk.last }
786
+ options[:class_name] = far_assoc.last[:inverse_table].singularize.camelize
787
+ options[:foreign_key] = far_assoc.last[:fk].to_sym
783
788
  end
784
789
  options[:source] = fk.last.to_sym unless hmt_name.singularize == fk.last
785
790
  code << " has_many :#{hmt_name}#{options.map { |opt| ", #{opt.first}: #{opt.last.inspect}" }.join}\n"
@@ -942,7 +947,6 @@ class Object
942
947
  }
943
948
  s
944
949
  end
945
- # binding.pry
946
950
  render inline: json.to_json, content_type: request.format
947
951
  return
948
952
  end
@@ -959,7 +963,8 @@ class Object
959
963
  return
960
964
  end
961
965
 
962
- order = pk.each_with_object([]) { |pk_part, s| s << "#{model.table_name}.#{pk_part}" }
966
+ quoted_table_name = model.table_name.split('.').map { |x| "\"#{x}\"" }.join('.')
967
+ order = pk.each_with_object([]) { |pk_part, s| s << "#{quoted_table_name}.\"#{pk_part}\"" }
963
968
  ar_relation = order.present? ? model.order("#{order.join(', ')}") : model.all
964
969
  @_brick_params = ar_relation.brick_select(params, (selects = []), (bt_descrip = {}), (hm_counts = {}), (join_array = ::Brick::JoinArray.new))
965
970
  # %%% Add custom HM count columns
@@ -974,7 +979,8 @@ class Object
974
979
  @_brick_join_array = join_array
975
980
  end
976
981
 
977
- if model&.primary_key
982
+ is_pk_string = nil
983
+ if (pk_col = model&.primary_key)
978
984
  code << " def show\n"
979
985
  code << (find_by_id = " id = params[:id]&.split(/[\\/,_]/)
980
986
  id = id.first if id.is_a?(Array) && id.length == 1
@@ -982,7 +988,12 @@ class Object
982
988
  code << " end\n"
983
989
  self.define_method :show do
984
990
  ::Brick.set_db_schema(params)
985
- id = params[:id]&.split(/[\/,_]/)
991
+ id = if model.columns_hash[pk_col]&.type == :string
992
+ is_pk_string = true
993
+ params[:id]
994
+ else
995
+ params[:id]&.split(/[\/,_]/)
996
+ end
986
997
  id = id.first if id.is_a?(Array) && id.length == 1
987
998
  instance_variable_set("@#{singular_table_name}".to_sym, model.find(id))
988
999
  end
@@ -1021,7 +1032,7 @@ class Object
1021
1032
  # return
1022
1033
  end
1023
1034
 
1024
- id = params[:id]&.split(/[\/,_]/)
1035
+ id = is_pk_string ? params[:id] : params[:id]&.split(/[\/,_]/)
1025
1036
  id = id.first if id.is_a?(Array) && id.length == 1
1026
1037
  instance_variable_set("@#{singular_table_name}".to_sym, (obj = model.find(id)))
1027
1038
  obj = obj.first if obj.is_a?(Array)
@@ -1047,19 +1058,15 @@ class Object
1047
1058
  end
1048
1059
 
1049
1060
  def _brick_get_hm_assoc_name(relation, hm_assoc)
1050
- if relation[:hm_counts][hm_assoc[:assoc_name]]&.> 1
1051
- # binding.pry if (same_name = relation[:fks].find { |x| x.last[:assoc_name] == hm_assoc[:assoc_name] && x.last != hm_assoc }) #&&
1052
- # x.last[:alternate_name] == hm_assoc[:alternate_name] })
1053
- # relation[:fks].any? { |k, v| v[:assoc_name] == new_alt_name }
1061
+ if (relation[:hm_counts][hm_assoc[:assoc_name]]&.> 1) &&
1062
+ hm_assoc[:alternate_name] != hm_assoc[:inverse][:assoc_name]
1054
1063
  plural = ActiveSupport::Inflector.pluralize(hm_assoc[:alternate_name])
1055
- # binding.pry if hm_assoc[:assoc_name] == 'issue_issue_duplicates'
1056
1064
  new_alt_name = (hm_assoc[:alternate_name] == name.underscore) ? "#{hm_assoc[:assoc_name].singularize}_#{plural}" : plural
1057
1065
  # uniq = 1
1058
1066
  # while same_name = relation[:fks].find { |x| x.last[:assoc_name] == hm_assoc[:assoc_name] && x.last != hm_assoc }
1059
1067
  # hm_assoc[:assoc_name] = "#{hm_assoc_name}_#{uniq += 1}"
1060
1068
  # end
1061
1069
  # puts new_alt_name
1062
- # binding.pry if new_alt_name == 'issue_duplicates'
1063
1070
  # hm_assoc[:assoc_name] = new_alt_name
1064
1071
  [new_alt_name, true]
1065
1072
  else
@@ -1178,7 +1185,8 @@ module ActiveRecord::ConnectionHandling
1178
1185
  case ActiveRecord::Base.connection.adapter_name
1179
1186
  when 'PostgreSQL', 'SQLite' # These bring back a hash for each row because the query uses column aliases
1180
1187
  # schema ||= 'public' if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
1181
- ActiveRecord::Base.execute_sql(sql, ActiveRecord::Base.internal_metadata_table_name, ActiveRecord::Base.schema_migrations_table_name).each do |r|
1188
+ ar_imtn = ActiveRecord.version >= ::Gem::Version.new('5.0') ? ActiveRecord::Base.internal_metadata_table_name : ''
1189
+ ActiveRecord::Base.execute_sql(sql, ActiveRecord::Base.schema_migrations_table_name, ar_imtn).each do |r|
1182
1190
  # If Apartment gem lists the table as being associated with a non-tenanted model then use whatever it thinks
1183
1191
  # is the default schema, usually 'public'.
1184
1192
  schema_name = if ::Brick.config.schema_behavior[:multitenant]
@@ -1364,7 +1372,7 @@ module Brick
1364
1372
  is_schema = if ::Brick.config.schema_behavior[:multitenant]
1365
1373
  # If Apartment gem lists the primary table as being associated with a non-tenanted model
1366
1374
  # then use 'public' schema for the primary table
1367
- if apartment&.excluded_models.include?(fk[4].singularize.camelize)
1375
+ if apartment && apartment&.excluded_models.include?(fk[4].singularize.camelize)
1368
1376
  fk[3] = Apartment.default_schema
1369
1377
  true
1370
1378
  end
@@ -1446,7 +1454,6 @@ module Brick
1446
1454
  else
1447
1455
  fk[1]
1448
1456
  end
1449
- # binding.pry if inv_tbl == 'issue_issue_duplicates' # inverse_table goofed?
1450
1457
  assoc_hm = hms[hm_cnstr_name] = { is_bt: false, fk: fk[2], assoc_name: for_tbl.pluralize, alternate_name: bt_assoc_name,
1451
1458
  inverse_table: inv_tbl, inverse: assoc_bt }
1452
1459
  assoc_hm[:polymorphic] = true if is_polymorphic
@@ -216,12 +216,17 @@ input[type=submit] {
216
216
  <% def is_bcrypt?(val)
217
217
  val.is_a?(String) && val.length == 60 && val.start_with?('$2a$')
218
218
  end
219
- def hide_bcrypt(val)
219
+ def hide_bcrypt(val, max_len = 200)
220
220
  if is_bcrypt?(val)
221
221
  '(hidden)'
222
- elsif val.is_a?(String) && val.encoding.name != 'UTF-8'
223
- val[0..1000].force_encoding('UTF-8')
224
222
  else
223
+ if val.is_a?(String)
224
+ if val.length > max_len
225
+ val = val[0...max_len]
226
+ val << '...'
227
+ end
228
+ val.force_encoding('UTF-8') unless val.encoding.name == 'UTF-8'
229
+ end
225
230
  val
226
231
  end
227
232
  end %>"
@@ -250,40 +255,44 @@ end %>"
250
255
  var schemaSelect = document.getElementById(\"schema\");
251
256
  var tblSelect = document.getElementById(\"tbl\");
252
257
  var brickSchema;
253
- if (schemaSelect) {
254
- brickSchema = changeout(location.href, \"_brick_schema\");
255
- if (brickSchema) {
256
- [... document.getElementsByTagName(\"A\")].forEach(function (a) { a.href = changeout(a.href, \"_brick_schema\", brickSchema); });
258
+
259
+ // This PageTransitionEvent fires when the page first loads, as well as after any other history
260
+ // transition such as when using the browser's Back and Forward buttons.
261
+ window.addEventListener(\"pageshow\", function() {
262
+ if (schemaSelect) { // First drop-down is only present if multitenant
263
+ brickSchema = changeout(location.href, \"_brick_schema\");
264
+ if (brickSchema) {
265
+ [... document.getElementsByTagName(\"A\")].forEach(function (a) { a.href = changeout(a.href, \"_brick_schema\", brickSchema); });
266
+ }
267
+ schemaSelect.value = brickSchema || \"public\";
268
+ schemaSelect.focus();
269
+ schemaSelect.addEventListener(\"change\", function () {
270
+ // If there's an ID then remove it (trim after selected table)
271
+ location.href = changeout(location.href, \"_brick_schema\", this.value, tblSelect.value);
272
+ });
257
273
  }
258
- schemaSelect.value = brickSchema || \"public\";
259
- schemaSelect.focus();
260
- schemaSelect.addEventListener(\"change\", function () {
261
- // If there's an ID then remove it (trim after selected table)
262
- location.href = changeout(location.href, \"_brick_schema\", this.value, tblSelect.value);
263
- });
264
- }
265
- [... document.getElementsByTagName(\"FORM\")].forEach(function (form) {
266
- if (brickSchema)
267
- form.action = changeout(form.action, \"_brick_schema\", brickSchema);
268
- form.addEventListener('submit', function (ev) {
269
- [... ev.target.getElementsByTagName(\"SELECT\")].forEach(function (select) {
270
- if (select.value === \"^^^brick_NULL^^^\")
271
- select.value = null;
274
+ [... document.getElementsByTagName(\"FORM\")].forEach(function (form) {
275
+ if (brickSchema)
276
+ form.action = changeout(form.action, \"_brick_schema\", brickSchema);
277
+ form.addEventListener('submit', function (ev) {
278
+ [... ev.target.getElementsByTagName(\"SELECT\")].forEach(function (select) {
279
+ if (select.value === \"^^^brick_NULL^^^\")
280
+ select.value = null;
281
+ });
282
+ return true;
272
283
  });
273
- return true;
274
284
  });
275
- });
276
285
 
277
- if (tblSelect) {
278
- tblSelect.value = changeout(location.href)[0];
279
- if (tblSelect.selectedIndex < 0) tblSelect.value = changeout(location.href)[1];
280
- tblSelect.addEventListener(\"change\", function () {
281
- var lhr = changeout(location.href, null, this.value);
282
- if (brickSchema)
283
- lhr = changeout(lhr, \"_brick_schema\", schemaSelect.value);
284
- location.href = lhr;
285
- });
286
- }
286
+ if (tblSelect) { // Always present
287
+ tblSelect.value = changeout(location.href)[schemaSelect ? 1 : 0];
288
+ tblSelect.addEventListener(\"change\", function () {
289
+ var lhr = changeout(location.href, null, this.value);
290
+ if (brickSchema)
291
+ lhr = changeout(lhr, \"_brick_schema\", schemaSelect.value);
292
+ location.href = lhr;
293
+ });
294
+ }
295
+ });
287
296
 
288
297
  function changeout(href, param, value, trimAfter) {
289
298
  var hrefParts = href.split(\"?\");
@@ -366,7 +375,6 @@ function changeout(href, param, value, trimAfter) {
366
375
 
367
376
  async function updateSignInStatus(isSignedIn) {
368
377
  if (isSignedIn) {
369
- console.log(\"turds!\");
370
378
  await gapi.client.sheets.spreadsheets.create({
371
379
  properties: {
372
380
  title: #{table_name.inspect},
@@ -455,7 +463,6 @@ function changeout(href, param, value, trimAfter) {
455
463
  ::Brick.config.metadata_columns.include?(k) || poly_cols.include?(k) || k.start_with?('_brfk_') || (k.start_with?('_br_') && (k.length == 63 || k.end_with?('_ct'))) %>
456
464
  <td>
457
465
  <% if (bt = bts[k]) %>
458
- <%# binding.pry # Postgres column names are limited to 63 characters %>
459
466
  <% if bt[2] # Polymorphic?
460
467
  bt_class = #{obj_name}.send(\"#\{bt.first\}_type\")
461
468
  base_class = (::Brick.existing_stis[bt_class] || bt_class).constantize.base_class.name.underscore
@@ -464,6 +471,7 @@ function changeout(href, param, value, trimAfter) {
464
471
  send(\"#\{base_class\}_path\".to_sym, poly_id)) if poly_id %><%
465
472
  else
466
473
  bt_txt = (bt_class = bt[1].first.first).brick_descrip(
474
+ # 0..62 because Postgres column names are limited to 63 characters
467
475
  #{obj_name}, (descrips = @_brick_bt_descrip[bt.first][bt_class])[0..-2].map { |z| #{obj_name}.send(z.last[0..62]) }, (bt_id_col = descrips.last)
468
476
  )
469
477
  bt_id = #{obj_name}.send(*bt_id_col) if bt_id_col&.present? %>
@@ -546,7 +554,7 @@ function changeout(href, param, value, trimAfter) {
546
554
  <% else case #{model_name}.column_for_attribute(k).type
547
555
  when :string, :text %>
548
556
  <% if is_bcrypt?(val) # || .readonly? %>
549
- <%= hide_bcrypt(val) %>
557
+ <%= hide_bcrypt(val, 1000) %>
550
558
  <% else %>
551
559
  <div class=\"wide-input\"><%= f.text_field k.to_sym %></div>
552
560
  <% end %>
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 34
8
+ TINY = 35
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
@@ -1,25 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_record/version'
4
-
5
- # ActiveRecord before 4.0 didn't have #version
6
- unless ActiveRecord.respond_to?(:version)
7
- module ActiveRecord
8
- def self.version
9
- ::Gem::Version.new(ActiveRecord::VERSION::STRING)
10
- end
11
- end
12
- end
13
-
14
- # In ActiveSupport older than 5.0, the duplicable? test tries to new up a BigDecimal,
15
- # and Ruby 2.6 and later deprecates #new. This removes the warning from BigDecimal.
16
- require 'bigdecimal'
17
- if (ruby_version = ::Gem::Version.new(RUBY_VERSION)) >= ::Gem::Version.new('2.6') &&
18
- ActiveRecord.version < ::Gem::Version.new('5.0')
19
- def BigDecimal.new(*args, **kwargs)
20
- BigDecimal(*args, **kwargs)
21
- end
22
- end
3
+ require 'brick/compatibility'
23
4
 
24
5
  # Allow ActiveRecord 4.0 and 4.1 to work with newer Ruby (>= 2.4) by avoiding a "stack level too deep"
25
6
  # error when ActiveSupport tries to smarten up Numeric by messing with Fixnum and Bignum at the end of:
@@ -45,8 +26,8 @@ end
45
26
  require 'brick/util'
46
27
 
47
28
  # Allow ActiveRecord < 3.2 to work with Ruby 2.7 and later
48
- if ActiveRecord.version < ::Gem::Version.new('3.2') &&
49
- ruby_version >= ::Gem::Version.new('2.7')
29
+ if (ruby_version = ::Gem::Version.new(RUBY_VERSION)) >= ::Gem::Version.new('2.7') &&
30
+ ActiveRecord.version < ::Gem::Version.new('3.2')
50
31
  # Remove circular reference for "now"
51
32
  ::Brick::Util._patch_require(
52
33
  'active_support/values/time_zone.rb', '/activesupport',
@@ -132,7 +113,6 @@ module Brick
132
113
  associatives = hms.each_with_object({}) do |hmt, s|
133
114
  if (through = hmt.last.options[:through])
134
115
  skip_hms[through] = nil
135
- # binding.pry if hmt.first == :issue_issues
136
116
  s[hmt.first] = hms[through] # End up with a hash of HMT names pointing to join-table associations
137
117
  elsif hmt.last.inverse_of.nil?
138
118
  puts "SKIPPING #{hmt.last.name.inspect}"
@@ -18,7 +18,8 @@ module Brick
18
18
  desc 'Generates an initializer file for configuring Brick'
19
19
 
20
20
  def create_initializer_file
21
- unless File.exist?(filename = 'config/initializers/brick.rb')
21
+ is_brick_file = File.exist?(filename = 'config/initializers/brick.rb')
22
+ if is_brick_file && ::Brick.config.schema_behavior[:multitenant] || !is_brick_file
22
23
  # See if we can make suggestions for additional_references and polymorphic associations
23
24
  resembles_fks = Hash.new { |h, k| h[k] = [] }
24
25
  possible_polymorphics = {}
@@ -223,7 +224,10 @@ module Brick
223
224
  # # Database schema to use when analysing existing data, such as deriving a list of polymorphic classes in the case that
224
225
  # # it wasn't originally specified.
225
226
  # Brick.schema_behavior = :namespaced
226
- # Brick.schema_behavior = { multitenant: { schema_to_analyse: 'engineering' } }
227
+ #{Brick.config.schema_behavior ? "Brick.schema_behavior = { multitenant: { schema_to_analyse: #{
228
+ Brick.config.schema_behavior[:multitenant][:schema_to_analyse].inspect}" :
229
+ "# Brick.schema_behavior = { multitenant: { schema_to_analyse: 'engineering'"
230
+ } } }
227
231
 
228
232
  # # Polymorphic associations are set up by providing a model name and polymorphic association name#{poly}
229
233
 
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.34
4
+ version: 1.0.35
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-23 00:00:00.000000000 Z
11
+ date: 2022-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -214,6 +214,7 @@ extensions: []
214
214
  extra_rdoc_files: []
215
215
  files:
216
216
  - lib/brick.rb
217
+ - lib/brick/compatibility.rb
217
218
  - lib/brick/config.rb
218
219
  - lib/brick/extensions.rb
219
220
  - lib/brick/frameworks/cucumber.rb