brick 1.0.110 → 1.0.112

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: 3d11240139b576ead983fbe9811f4476b8819878068c46db852b515fbc0849c6
4
- data.tar.gz: 2db932779fcd8517f7e5be524ce387061d4e8cab193715be76893dc1e675d1c9
3
+ metadata.gz: 69051263cec00b3672b8d48b0c595ff6875b81f27e7995be72a03d6699ad6d02
4
+ data.tar.gz: 217687ad2f6b93c33dc781f5930a0475a60fb27d782593109055beaae19f4e55
5
5
  SHA512:
6
- metadata.gz: dd22a1ab8d2b13f2d289fe02262ae8aecb3be921094bbb5dd0392fe5cd46ecadda259e72a18c3ecb7daea0fd5f5a50d697383a4bb949b068976e3b6007769d04
7
- data.tar.gz: 39d26f6c99511d3651003c660fed495223ebd4fb34865b1eaa3b8554e294ed0fb3672b17e7dc43ca43fecbd1b7dda2ec6b9a4371025880e12c83694f45557173
6
+ metadata.gz: 6eff4c8a9f59673d14be1d890b067e17e631b1d6938a22b81c1ec45c3785489195d5d9e93939a38c681d36d844df2ad9a932584d8269b0fd2ef678de428c805c
7
+ data.tar.gz: 723425258d449708f18e086f289147b3402f728c93fbcba3a16654c3d15b4fe715022e427cb3f87e731bf9b73d693a5d4f43a500bdbde3641b69ac61e4c35e35
@@ -2019,6 +2019,21 @@ end.class_exec do
2019
2019
  # .default_schema are specified then we can work with non-tenanted models more appropriately
2020
2020
  if (apartment = Object.const_defined?('Apartment')) &&
2021
2021
  File.exist?(apartment_initializer = ::Rails.root.join('config/initializers/apartment.rb'))
2022
+ require 'apartment/adapters/abstract_adapter'
2023
+ Apartment::Adapters::AbstractAdapter.class_exec do
2024
+ if instance_methods.include?(:process_excluded_models)
2025
+ def process_excluded_models
2026
+ # All other models will share a connection (at Apartment.connection_class) and we can modify at will
2027
+ Apartment.excluded_models.each do |excluded_model|
2028
+ begin
2029
+ process_excluded_model(excluded_model)
2030
+ rescue NameError => e
2031
+ (@bad_models ||= []) << excluded_model
2032
+ end
2033
+ end
2034
+ end
2035
+ end
2036
+ end
2022
2037
  unless @_apartment_loaded
2023
2038
  load apartment_initializer
2024
2039
  @_apartment_loaded = true
@@ -2057,13 +2072,27 @@ end.class_exec do
2057
2072
  schema = possible_schema
2058
2073
  orig_schema = ActiveRecord::Base.execute_sql('SELECT current_schemas(true)').first['current_schemas'][1..-2].split(',')
2059
2074
  ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?", schema)
2060
- elsif Rails.env == 'test' # When testing, just find the most recently-created schema
2061
- ::Brick.default_schema = schema = ::Brick.db_schemas.to_a.sort { |a, b| b.last[:dt] <=> a.last[:dt] }.first.first
2062
- puts "While running tests, had noticed in the brick.rb initializer that the line \"::Brick.schema_behavior = ...\" refers to a schema called \"#{possible_schema}\" which does not exist. Reading table structure from the most recently-created schema, #{schema}."
2075
+ # When testing, just find the most recently-created schema
2076
+ elsif begin
2077
+ Rails.env == 'test' ||
2078
+ ActiveRecord::Base.execute_sql("SELECT value FROM ar_internal_metadata WHERE key='environment';").first&.fetch('value', nil) == 'test'
2079
+ rescue
2080
+ end
2081
+ ::Brick.default_schema = ::Brick.apartment_default_tenant
2082
+ ::Brick.test_schema = schema = ::Brick.db_schemas.to_a.sort { |a, b| b.last[:dt] <=> a.last[:dt] }.first.first
2083
+ if possible_schema.blank?
2084
+ puts "While running tests, using the most recently-created schema, #{schema}."
2085
+ else
2086
+ puts "While running tests, had noticed in the brick.rb initializer that the line \"::Brick.schema_behavior = ...\" refers to a schema called \"#{possible_schema}\" which does not exist. Reading table structure from the most recently-created schema, #{schema}."
2087
+ end
2063
2088
  orig_schema = ActiveRecord::Base.execute_sql('SELECT current_schemas(true)').first['current_schemas'][1..-2].split(',')
2089
+ ::Brick.config.schema_behavior = { multitenant: {} } # schema_to_analyse: [schema]
2064
2090
  ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?", schema)
2065
2091
  else
2066
2092
  puts "*** In the brick.rb initializer the line \"::Brick.schema_behavior = ...\" refers to schema(s) called #{possible_schemas.map { |s| "\"#{s}\"" }.join(', ')}. No mentioned schema exists. ***"
2093
+ if ::Brick.db_schemas.key?(::Brick.apartment_default_tenant)
2094
+ ::Brick.default_schema = schema = ::Brick.apartment_default_tenant
2095
+ end
2067
2096
  end
2068
2097
  end
2069
2098
  when 'Mysql2', 'Trilogy'
@@ -36,11 +36,12 @@ module Brick
36
36
  // This PageTransitionEvent fires when the page first loads, as well as after any other history
37
37
  // transition such as when using the browser's Back and Forward buttons.
38
38
  window.addEventListener(\"pageshow\", linkSchemas);
39
- var brickSchema;
39
+ var brickSchema,
40
+ brickTestSchema;
40
41
  function linkSchemas() {
41
42
  var schemaSelect = document.getElementById(\"schema\");
42
43
  var tblSelect = document.getElementById(\"tbl\");
43
- if (tblSelect) { // Always present
44
+ if (tblSelect) { // Always present for Brick pages
44
45
  // Used to be: var i = # {::Brick.config.path_prefix ? '0' : 'schemaSelect ? 1 : 0'},
45
46
  var changeoutList = changeout(location.href);
46
47
  for (var i = 0; i < changeoutList.length; ++i) {
@@ -53,32 +54,32 @@ function linkSchemas() {
53
54
  if (brickSchema) lhr = changeout(lhr, \"_brick_schema\", schemaSelect.value);
54
55
  location.href = lhr;
55
56
  });
56
- }
57
57
 
58
- if (schemaSelect) { // First drop-down is only present if multitenant
59
- if (brickSchema = changeout(location.href, \"_brick_schema\")) {
60
- [... document.getElementsByTagName(\"A\")].forEach(function (a) { a.href = changeout(a.href, \"_brick_schema\", brickSchema); });
61
- }
62
- if (schemaSelect.options.length > 1) {
63
- schemaSelect.value = brickSchema || \"public\";
64
- schemaSelect.addEventListener(\"change\", function () {
65
- // If there's an ID then remove it (trim after selected table)
66
- location.href = changeout(location.href, \"_brick_schema\", this.value, tblSelect.value);
67
- });
58
+ if (schemaSelect) { // First drop-down is only present if multitenant
59
+ if (brickSchema = changeout(location.href, \"_brick_schema\")) {
60
+ [... document.getElementsByTagName(\"A\")].forEach(function (a) { a.href = changeout(a.href, \"_brick_schema\", brickSchema); });
61
+ }
62
+ if (schemaSelect.options.length > 1) {
63
+ schemaSelect.value = brickSchema || brickTestSchema || \"public\";
64
+ schemaSelect.addEventListener(\"change\", function () {
65
+ // If there's an ID then remove it (trim after selected table)
66
+ location.href = changeout(location.href, \"_brick_schema\", this.value, tblSelect.value);
67
+ });
68
+ }
68
69
  }
69
- }
70
- tblSelect.focus();
71
-
72
- [... document.getElementsByTagName(\"FORM\")].forEach(function (form) {
73
- if (brickSchema)
74
- form.action = changeout(form.action, \"_brick_schema\", brickSchema);
75
- form.addEventListener('submit', function (ev) {
76
- [... ev.target.getElementsByTagName(\"SELECT\")].forEach(function (select) {
77
- if (select.value === \"^^^brick_NULL^^^\") select.value = null;
70
+ tblSelect.focus();
71
+
72
+ [... document.getElementsByTagName(\"FORM\")].forEach(function (form) {
73
+ if (brickSchema)
74
+ form.action = changeout(form.action, \"_brick_schema\", brickSchema);
75
+ form.addEventListener('submit', function (ev) {
76
+ [... ev.target.getElementsByTagName(\"SELECT\")].forEach(function (select) {
77
+ if (select.value === \"^^^brick_NULL^^^\") select.value = null;
78
+ });
79
+ return true;
78
80
  });
79
- return true;
80
81
  });
81
- });
82
+ }
82
83
  };
83
84
  "
84
85
 
@@ -321,18 +322,26 @@ window.addEventListener(\"popstate\", linkSchemas);
321
322
  end
322
323
 
323
324
  def set_brick_model(find_args)
324
- # Need to return true if we can fill in the blanks for a missing one
325
- # args will be something like: ["index", ["categories"]]
326
- if (class_name = find_args[1].last&.singularize)
327
- find_args[1][find_args[1].length - 1] = class_name # Make sure the last item, defining the class name, is singular
328
- if (model = find_args[1].map(&:camelize).join('::').constantize) && (
329
- ['index', 'show'].include?(find_args.first) || # Everything has index and show
330
- # Only CUD stuff has create / update / destroy
331
- (!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(find_args.first))
332
- )
333
- @_brick_model = model
325
+ # Return an appropriate model for a given view template request.
326
+ # find_args will generally be something like: ["index", ["categories"]]
327
+ # and must cycle through all of find_args[1] because in some cases such as with Devise we get something like:
328
+ # ["create", ["users/sessions", "sessions", "devise/sessions", "devise", "application"], false, []]
329
+ find_args[1]&.any? do |resource_name|
330
+ if (class_name = (resource_parts = resource_name.split('/')).last&.singularize)
331
+ resource_parts[-1] = class_name # Make sure the last part, defining the class name, is singular
332
+ begin
333
+ if (model = Object.const_get(resource_parts.map(&:camelize).join('::')))&.is_a?(Class) && (
334
+ ['index', 'show'].include?(find_args.first) || # Everything has index and show
335
+ # Only CUD stuff has create / update / destroy
336
+ (!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(find_args.first))
337
+ )
338
+ @_brick_model = model
339
+ end
340
+ rescue
341
+ end
334
342
  end
335
343
  end
344
+ @_brick_model
336
345
  end
337
346
 
338
347
  def path_keys(hm_assoc, fk_name, pk)
@@ -355,22 +364,20 @@ window.addEventListener(\"popstate\", linkSchemas);
355
364
 
356
365
  alias :_brick_find_template :find_template
357
366
  def find_template(*args, **options)
367
+ find_template_err = nil
358
368
  unless (model_name = @_brick_model&.name) ||
359
369
  (is_status = ::Brick.config.add_status && args[0..1] == ['status', ['brick_gem']]) ||
360
370
  (is_orphans = ::Brick.config.add_orphans && args[0..1] == ['orphans', ['brick_gem']]) ||
361
371
  (is_crosstab = args[0..1] == ['crosstab', ['brick_gem']])
362
- if ActionView.version < ::Gem::Version.new('5.0') # %%% Not sure if this should be perhaps 4.2 instead
363
- begin
364
- if (possible_template = _brick_find_template(*args, **options))
365
- return possible_template
366
- end
367
- rescue
372
+ begin
373
+ if (possible_template = _brick_find_template(*args, **options))
374
+ return possible_template
368
375
  end
369
- elsif (possible_template = _brick_find_template(*args, **options))
370
- return possible_template
376
+ rescue StandardError => e
377
+ find_template_err = e # Can come up with stuff like Devise which has its own view templates
371
378
  end
372
379
  # Used to also have: ActionView.version < ::Gem::Version.new('5.0') &&
373
- model_name = (args[1].is_a?(Array) ? set_brick_model(args) : nil)&.name
380
+ model_name = set_brick_model(args)&.name
374
381
  end
375
382
 
376
383
  if @_brick_model
@@ -851,8 +858,9 @@ document.querySelectorAll(\"input[type=submit][data-confirm]\").forEach(function
851
858
  });
852
859
  });
853
860
 
854
- #{JS_CHANGEOUT}
855
-
861
+ #{JS_CHANGEOUT}#{
862
+ "\nbrickTestSchema = \"#{::Brick.test_schema}\";" if ::Brick.test_schema
863
+ }
856
864
  // Snag first TR for sticky header
857
865
  var grid = document.getElementById(\"#{table_name}\");
858
866
  #{table_name}HtColumns = grid && [grid.getElementsByTagName(\"TR\")[0]];
@@ -1156,7 +1164,7 @@ erDiagram
1156
1164
  td_count += 1 %>
1157
1165
  <td><%= link_to_brick(
1158
1166
  avo_svg,
1159
- { index_proc: Proc.new do |avo_model, relation|
1167
+ { index_proc: Proc.new do |_avo_model, relation|
1160
1168
  path_helper = \"resources_#\{relation.fetch(:auto_prefixed_schema, nil)}#\{model.model_name.route_key}_path\".to_sym
1161
1169
  ::Avo.railtie_routes_url_helpers.send(path_helper) if ::Avo.railtie_routes_url_helpers.respond_to?(path_helper)
1162
1170
  end,
@@ -1438,11 +1446,9 @@ end
1438
1446
  <% when :boolean %>
1439
1447
  <%= f.check_box k.to_sym %>
1440
1448
  <% when :integer, :decimal, :float %>
1441
- <%= if col_type == :integer
1442
- f.text_field k.to_sym, { pattern: '\\d*', class: 'check-validity' }
1443
- else
1444
- f.number_field k.to_sym
1445
- end %>
1449
+ <%= digit_pattern = col_type == :integer ? '\\d*' : '\\d*(?:\\.\\d*|)'
1450
+ # Used to do this for float / decimal: f.number_field k.to_sym
1451
+ f.text_field k.to_sym, { pattern: digit_pattern, class: 'check-validity' } %>
1446
1452
  <% when *dt_pickers.keys
1447
1453
  is_includes_dates = true %>
1448
1454
  <%= f.text_field k.to_sym, { class: dt_pickers[col_type] } %>
@@ -1544,7 +1550,12 @@ end}
1544
1550
  </body>
1545
1551
  </html>
1546
1552
  "
1547
-
1553
+ else # args.first isn't index / show / edit / new / orphans / status
1554
+ if find_template_err # Can surface when gems have their own view templates
1555
+ raise find_template_err
1556
+ else # Can surface if someone made their own controller which has a screwy action
1557
+ puts "Couldn't work with action #{args.first}"
1558
+ end
1548
1559
  end
1549
1560
  unless is_crosstab
1550
1561
  inline << "
@@ -201,6 +201,7 @@ module Brick::Rails::FormTags
201
201
  end
202
202
  filter = "?#{filter_parts.join('&')}" if filter_parts.present?
203
203
  app_routes = Rails.application.routes # In case we're operating in another engine, reference the application since Brick routes are placed there.
204
+ relation = ::Brick.relations.fetch(rel_name || args.first.table_name, nil)
204
205
  if (klass_or_obj&.is_a?(Class) && klass_or_obj < ActiveRecord::Base) ||
205
206
  (klass_or_obj&.is_a?(ActiveRecord::Base) && klass_or_obj.new_record? && (klass_or_obj = klass_or_obj.class))
206
207
  path = (proc = kwargs[:index_proc]) ? proc.call(klass_or_obj, relation) : "#{app_routes.path_for(controller: klass_or_obj.base_class._brick_index(nil, '/', relation), action: :index)}#{filter}"
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 110
8
+ TINY = 112
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
@@ -135,7 +135,8 @@ module Brick
135
135
  @existing_stis ||= Brick.config.sti_namespace_prefixes.each_with_object({}) { |snp, s| s[snp.first[2..-1]] = snp.last unless snp.first.end_with?('::') }
136
136
  end
137
137
 
138
- attr_accessor :default_schema, :db_schemas, :routes_done, :is_oracle, :is_eager_loading, :auto_models, :initializer_loaded
138
+ attr_accessor :default_schema, :db_schemas, :test_schema,
139
+ :routes_done, :is_oracle, :is_eager_loading, :auto_models, :initializer_loaded
139
140
 
140
141
  def set_db_schema(params = nil)
141
142
  # If Apartment::Tenant.current is not still the default (usually 'public') then an elevator has brought us into
@@ -148,6 +149,10 @@ module Brick
148
149
  ::Brick.db_schemas&.key?(schema)
149
150
  Apartment::Tenant.switch!(schema)
150
151
  schema
152
+ elsif ::Brick.test_schema
153
+ is_show_schema_list = true
154
+ Apartment::Tenant.switch!(::Brick.test_schema)
155
+ ::Brick.test_schema
151
156
  else
152
157
  current_schema # Just return the current schema
153
158
  end
@@ -1497,12 +1502,12 @@ module ActiveRecord
1497
1502
  # entry in your .select().
1498
1503
  # More information: https://discuss.rubyonrails.org/t/includes-and-select-for-joined-data/81640
1499
1504
  def apply_column_aliases(relation)
1500
- if (sel_vals = relation.select_values.map(&:to_s)).first == '_brick_eager_load'
1505
+ if !(@join_root_alias = relation.select_values.empty?) &&
1506
+ relation.select_values.first.to_s == '_brick_eager_load'
1507
+ relation.select_values.shift
1501
1508
  used_cols = {}
1502
1509
  # Find and expand out all column names being used in select(...)
1503
- new_select_values = sel_vals.each_with_object([]) do |col, s|
1504
- next if col == '_brick_eager_load'
1505
-
1510
+ new_select_values = relation.select_values.map(&:to_s).each_with_object([]) do |col, s|
1506
1511
  if col.include?(' ') # Some expression? (No chance for a simple column reference)
1507
1512
  s << col # Just pass it through
1508
1513
  else
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.110
4
+ version: 1.0.112
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-01-30 00:00:00.000000000 Z
11
+ date: 2023-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord