brick 1.0.36 → 1.0.39
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 +4 -4
- data/lib/brick/compatibility.rb +10 -1
- data/lib/brick/extensions.rb +10 -5
- data/lib/brick/frameworks/rails/engine.rb +80 -30
- data/lib/brick/util.rb +16 -9
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +133 -11
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 965d31143248d85fd47cf2445a266fb9d26cc5eb814330cbdbfb37d50570b5a0
|
4
|
+
data.tar.gz: d4f070e1c01b3922a610a4385fde6f6b4f345892d68d6b872e1294a33f4b1e61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70ea705efad428abb335e05569284caabe908c65efd679fffcd044894083626ca432366a65305bcd50506a7ca13169bac9cc2f7354728c3b8f23e4ed0aba7094
|
7
|
+
data.tar.gz: b61096e6deadf323cc8784bcf93ae5faf72eae02fef3059b002c57bac035b30858da73bb59bd2f0572168a90b39062645580cd120e1d78665f5c909258727ad8
|
data/lib/brick/compatibility.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_record/version'
|
4
|
-
|
5
4
|
# ActiveRecord before 4.0 didn't have #version
|
6
5
|
unless ActiveRecord.respond_to?(:version)
|
7
6
|
module ActiveRecord
|
@@ -11,6 +10,16 @@ unless ActiveRecord.respond_to?(:version)
|
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
13
|
+
require 'action_view'
|
14
|
+
# Older ActionView didn't have #version
|
15
|
+
unless ActionView.respond_to?(:version)
|
16
|
+
module ActionView
|
17
|
+
def self.version
|
18
|
+
ActionPack.version
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
14
23
|
# In ActiveSupport older than 5.0, the duplicable? test tries to new up a BigDecimal,
|
15
24
|
# and Ruby 2.6 and later deprecates #new. This removes the warning from BigDecimal.
|
16
25
|
# This compatibility needs to be put into place in the application's "config/boot.rb"
|
data/lib/brick/extensions.rb
CHANGED
@@ -204,7 +204,7 @@ module ActiveRecord
|
|
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
206
|
av_class = Class.new.extend(ActionView::Helpers::UrlHelper)
|
207
|
-
av_class.extend(ActionView::Helpers::TagHelper) if ActionView.version < ::Gem::Version.new('
|
207
|
+
av_class.extend(ActionView::Helpers::TagHelper) if ActionView.version < ::Gem::Version.new('7')
|
208
208
|
link = av_class.link_to(name, model_path)
|
209
209
|
model_underscore == assoc_name ? link : "#{assoc_name}-#{link}".html_safe
|
210
210
|
end
|
@@ -552,7 +552,7 @@ Module.class_exec do
|
|
552
552
|
# return my_const
|
553
553
|
end
|
554
554
|
|
555
|
-
relations = ::Brick.
|
555
|
+
relations = ::Brick.relations
|
556
556
|
# puts "ON OBJECT: #{args.inspect}" if self.module_parent == Object
|
557
557
|
result = if ::Brick.enable_controllers? && class_name.end_with?('Controller') && (plural_class_name = class_name[0..-11]).length.positive?
|
558
558
|
# Otherwise now it's up to us to fill in the gaps
|
@@ -627,8 +627,8 @@ Module.class_exec do
|
|
627
627
|
# module_prefixes.unshift('') unless module_prefixes.first.blank?
|
628
628
|
# candidate_file = Rails.root.join('app/models' + module_prefixes.map(&:underscore).join('/') + '.rb')
|
629
629
|
self._brick_const_missing(*args)
|
630
|
-
elsif self != Object
|
631
|
-
|
630
|
+
# elsif self != Object
|
631
|
+
# module_parent.const_missing(*args)
|
632
632
|
else
|
633
633
|
puts "MISSING! #{self.name} #{args.inspect} #{table_name}"
|
634
634
|
self._brick_const_missing(*args)
|
@@ -1188,8 +1188,13 @@ module ActiveRecord::ConnectionHandling
|
|
1188
1188
|
case ActiveRecord::Base.connection.adapter_name
|
1189
1189
|
when 'PostgreSQL', 'SQLite' # These bring back a hash for each row because the query uses column aliases
|
1190
1190
|
# schema ||= 'public' if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
1191
|
+
ar_smtn = if ActiveRecord::Base.respond_to?(:schema_migrations_table_name)
|
1192
|
+
ActiveRecord::Base.schema_migrations_table_name
|
1193
|
+
else
|
1194
|
+
'schema_migrations'
|
1195
|
+
end
|
1191
1196
|
ar_imtn = ActiveRecord.version >= ::Gem::Version.new('5.0') ? ActiveRecord::Base.internal_metadata_table_name : ''
|
1192
|
-
ActiveRecord::Base.execute_sql(sql,
|
1197
|
+
ActiveRecord::Base.execute_sql(sql, ar_smtn, ar_imtn).each do |r|
|
1193
1198
|
# If Apartment gem lists the table as being associated with a non-tenanted model then use whatever it thinks
|
1194
1199
|
# is the default schema, usually 'public'.
|
1195
1200
|
schema_name = if ::Brick.config.schema_behavior[:multitenant]
|
@@ -50,23 +50,26 @@ module Brick
|
|
50
50
|
# ====================================
|
51
51
|
if ::Brick.enable_views?
|
52
52
|
ActionView::LookupContext.class_exec do
|
53
|
+
# Used by Rails 5.0 and above
|
53
54
|
alias :_brick_template_exists? :template_exists?
|
54
55
|
def template_exists?(*args, **options)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
56
|
+
_brick_template_exists?(*args, **options) || set_brick_model(args)
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_brick_model(find_args)
|
60
|
+
# Need to return true if we can fill in the blanks for a missing one
|
61
|
+
# args will be something like: ["index", ["categories"]]
|
62
|
+
find_args[1] = find_args[1].each_with_object([]) { |a, s| s.concat(a.split('/')) }
|
63
|
+
if (class_name = find_args[1].last&.singularize)
|
64
|
+
find_args[1][find_args[1].length - 1] = class_name # Make sure the last item, defining the class name, is singular
|
65
|
+
if (model = find_args[1].map(&:camelize).join('::').constantize) && (
|
66
|
+
['index', 'show'].include?(find_args.first) || # Everything has index and show
|
63
67
|
# Only CUD stuff has create / update / destroy
|
64
|
-
|
68
|
+
(!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(find_args.first))
|
65
69
|
)
|
66
70
|
@_brick_model = model
|
67
71
|
end
|
68
72
|
end
|
69
|
-
is_template_exists
|
70
73
|
end
|
71
74
|
|
72
75
|
def path_keys(hm_assoc, fk_name, obj_name, pk)
|
@@ -82,9 +85,13 @@ module Brick
|
|
82
85
|
|
83
86
|
alias :_brick_find_template :find_template
|
84
87
|
def find_template(*args, **options)
|
85
|
-
|
88
|
+
unless (model_name = (
|
89
|
+
@_brick_model ||
|
90
|
+
(ActionView.version < ::Gem::Version.new('5.0') && args[1].is_a?(Array) ? set_brick_model(args) : nil)
|
91
|
+
)&.name)
|
92
|
+
return _brick_find_template(*args, **options)
|
93
|
+
end
|
86
94
|
|
87
|
-
model_name = @_brick_model.name
|
88
95
|
pk = @_brick_model._brick_primary_key(::Brick.relations.fetch(model_name, nil))
|
89
96
|
obj_name = model_name.split('::').last.underscore
|
90
97
|
path_obj_name = model_name.underscore.tr('/', '_')
|
@@ -141,9 +148,14 @@ module Brick
|
|
141
148
|
display: none;
|
142
149
|
}
|
143
150
|
|
151
|
+
#headerTop {
|
152
|
+
position: sticky;
|
153
|
+
top: 0px;
|
154
|
+
background-color: white;
|
155
|
+
z-index: 1;
|
156
|
+
}
|
144
157
|
table {
|
145
158
|
border-collapse: collapse;
|
146
|
-
margin: 25px 0;
|
147
159
|
font-size: 0.9em;
|
148
160
|
font-family: sans-serif;
|
149
161
|
min-width: 400px;
|
@@ -255,6 +267,7 @@ end %>"
|
|
255
267
|
var schemaSelect = document.getElementById(\"schema\");
|
256
268
|
var tblSelect = document.getElementById(\"tbl\");
|
257
269
|
var brickSchema;
|
270
|
+
var #{table_name}HtColumns;
|
258
271
|
|
259
272
|
// This PageTransitionEvent fires when the page first loads, as well as after any other history
|
260
273
|
// transition such as when using the browser's Back and Forward buttons.
|
@@ -316,6 +329,42 @@ function changeout(href, param, value, trimAfter) {
|
|
316
329
|
params[param] = value;
|
317
330
|
return hrefParts[0] + \"?\" + Object.keys(params).reduce(function (s, v) { s.push(v + \"=\" + params[v]); return s; }, []).join(\"&\");
|
318
331
|
}
|
332
|
+
|
333
|
+
// Snag first TR for sticky header
|
334
|
+
var grid = document.getElementById(\"#{table_name}\");
|
335
|
+
#{table_name}HtColumns = grid && [grid.getElementsByTagName(\"TR\")[0]];
|
336
|
+
var headerTop = document.getElementById(\"headerTop\");
|
337
|
+
function setHeaderSizes() {
|
338
|
+
// console.log(\"start\");
|
339
|
+
// See if the headerTop is already populated
|
340
|
+
// %%% Grab the TRs from headerTop, clear it out, do this stuff, add them back
|
341
|
+
headerTop.innerHTML = \"\"; // %%% Would love to not have to clear it out like this every time! (Currently doing this to support resize events.)
|
342
|
+
var isEmpty = headerTop.childElementCount === 0;
|
343
|
+
// Set up proper sizings of sticky column header
|
344
|
+
var node;
|
345
|
+
for (var j = 0; j < #{table_name}HtColumns.length; ++j) {
|
346
|
+
var row = #{table_name}HtColumns[j];
|
347
|
+
var tr = isEmpty ? document.createElement(\"TR\") : headerTop.childNodes[j];
|
348
|
+
tr.innerHTML = row.innerHTML.trim();
|
349
|
+
// Match up widths from the original column headers
|
350
|
+
for (var i = 0; i < row.childNodes.length; ++i) {
|
351
|
+
node = row.childNodes[i];
|
352
|
+
if (node.nodeType === 1) {
|
353
|
+
var style = tr.childNodes[i].style;
|
354
|
+
style.minWidth = style.maxWidth = getComputedStyle(node).width;
|
355
|
+
}
|
356
|
+
}
|
357
|
+
if (isEmpty) headerTop.appendChild(tr);
|
358
|
+
}
|
359
|
+
grid.style.marginTop = \"-\" + getComputedStyle(headerTop).height;
|
360
|
+
// console.log(\"end\");
|
361
|
+
}
|
362
|
+
if (headerTop) {
|
363
|
+
setHeaderSizes();
|
364
|
+
window.addEventListener('resize', function(event) {
|
365
|
+
setHeaderSizes();
|
366
|
+
}, true);
|
367
|
+
}
|
319
368
|
</script>"
|
320
369
|
inline = case args.first
|
321
370
|
when 'index'
|
@@ -415,13 +464,13 @@ function changeout(href, param, value, trimAfter) {
|
|
415
464
|
end
|
416
465
|
# %%% Instead of our current "for Janet Leverling (Employee)" kind of link we previously had this code that did a "where x = 123" thing:
|
417
466
|
# (where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %>)
|
418
|
-
|
467
|
+
"#{css}
|
419
468
|
<p style=\"color: green\"><%= notice %></p>#{"
|
420
469
|
<select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
|
421
470
|
<select id=\"tbl\">#{table_options}</select>
|
422
471
|
<h1>#{model_plural = model_name.pluralize}</h1>#{template_link}<%
|
423
|
-
if (relation = Brick.relations[#{model_name}.table_name])
|
424
|
-
|
472
|
+
if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)) %><%=
|
473
|
+
description %><br><%
|
425
474
|
end
|
426
475
|
if @_brick_params&.present? %>
|
427
476
|
<% if @_brick_params.length == 1 # %%% Does not yet work with composite keys
|
@@ -435,16 +484,18 @@ x = "#{css}
|
|
435
484
|
end %>
|
436
485
|
(<%= link_to 'See all #{model_plural.split('::').last}', #{path_obj_name.pluralize}_path %>)
|
437
486
|
<% end %>
|
487
|
+
<br>
|
488
|
+
<table id=\"headerTop\">
|
438
489
|
<table id=\"#{table_name}\">
|
439
|
-
<thead><tr>#{'<th></th>' if pk.present?}
|
440
|
-
|
490
|
+
<thead><tr>#{'<th></th>' if pk.present?}<%
|
491
|
+
col_order = []
|
441
492
|
@#{table_name}.columns.each do |col|
|
442
493
|
col_name = col.name
|
443
494
|
next if (#{(pk || []).inspect}.include?(col_name) && col.type == :integer && !bts.key?(col_name)) ||
|
444
495
|
::Brick.config.metadata_columns.include?(col_name) || poly_cols.include?(col_name)
|
445
496
|
|
446
|
-
col_order << col_name
|
447
|
-
|
497
|
+
col_order << col_name
|
498
|
+
%><th<%= \" title = \\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %>><%
|
448
499
|
if (bt = bts[col_name]) %>
|
449
500
|
BT <%
|
450
501
|
bt[1].each do |bt_pair| %><%=
|
@@ -453,11 +504,11 @@ x = "#{css}
|
|
453
504
|
else %><%=
|
454
505
|
col_name %><%
|
455
506
|
end
|
456
|
-
%></th
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
</tr></thead>
|
507
|
+
%></th><%
|
508
|
+
end
|
509
|
+
# Consider getting the name from the association -- h.first.name -- if a more \"friendly\" alias should be used for a screwy table name
|
510
|
+
%>#{hms_headers.map { |h| "<th>#{h[1]} <%= link_to('#{h[2]}', #{h.first.klass.name.underscore.tr('/', '_').pluralize}_path) %></th>" }.join
|
511
|
+
}</tr></thead>
|
461
512
|
|
462
513
|
<tbody>
|
463
514
|
<% @#{table_name}.each do |#{obj_name}| %>
|
@@ -495,19 +546,18 @@ x = "#{css}
|
|
495
546
|
|
496
547
|
#{"<hr><%= link_to \"New #{obj_name}\", new_#{path_obj_name}_path %>" unless @_brick_model.is_view?}
|
497
548
|
#{script}"
|
498
|
-
puts x
|
499
|
-
x
|
500
549
|
when 'show', 'update'
|
501
550
|
"#{css}
|
502
551
|
<p style=\"color: green\"><%= notice %></p>#{"
|
503
552
|
<select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
|
504
553
|
<select id=\"tbl\">#{table_options}</select>
|
505
554
|
<h1>#{model_name}: <%= (obj = @#{obj_name})&.brick_descrip || controller_name %></h1><%
|
506
|
-
if (relation = Brick.relations[#{model_name}.table_name])
|
507
|
-
|
555
|
+
if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)) %><%=
|
556
|
+
description %><br><%
|
508
557
|
end
|
509
558
|
%><%= link_to '(See all #{obj_name.pluralize})', #{path_obj_name.pluralize}_path %>
|
510
559
|
<% if obj %>
|
560
|
+
<br><br>
|
511
561
|
<%= # path_options = [obj.#{pk}]
|
512
562
|
# path_options << { '_brick_schema': } if
|
513
563
|
# url = send(:#{model_name.underscore}_path, obj.#{pk})
|
@@ -519,7 +569,7 @@ end
|
|
519
569
|
<tr>
|
520
570
|
<% next if (#{(pk || []).inspect}.include?(k) && !bts.key?(k)) ||
|
521
571
|
::Brick.config.metadata_columns.include?(k) %>
|
522
|
-
<th class=\"show-field\"<%= \" title = \\\"#\{col.comment}\\\"\".html_safe
|
572
|
+
<th class=\"show-field\"<%= \" title = \\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %>>
|
523
573
|
<% has_fields = true
|
524
574
|
if (bt = bts[k])
|
525
575
|
# Add a final member in this array with descriptive options to be used in <select> drop-downs
|
data/lib/brick/util.rb
CHANGED
@@ -5,7 +5,7 @@ module Brick
|
|
5
5
|
module Util
|
6
6
|
# ===================================
|
7
7
|
# Epic require patch
|
8
|
-
def self._patch_require(module_filename, folder_matcher,
|
8
|
+
def self._patch_require(module_filename, folder_matcher, replacements, autoload_symbol = nil, is_bundler = false)
|
9
9
|
mod_name_parts = module_filename.split('.')
|
10
10
|
extension = case mod_name_parts.last
|
11
11
|
when 'rb', 'so', 'o'
|
@@ -28,10 +28,13 @@ module Brick
|
|
28
28
|
Dir.mkdir(new_part) unless Dir.exist?(new_part)
|
29
29
|
new_part
|
30
30
|
end
|
31
|
-
if ::Brick::Util._write_patched(folder_matcher, module_filename, extension, custom_require_dir, nil,
|
31
|
+
if ::Brick::Util._write_patched(folder_matcher, module_filename, extension, custom_require_dir, nil, replacements) &&
|
32
32
|
!alp.include?(custom_require_dir)
|
33
33
|
alp.unshift(custom_require_dir)
|
34
34
|
end
|
35
|
+
# require 'pry-byebug'
|
36
|
+
# binding.pry
|
37
|
+
# z = 10
|
35
38
|
elsif is_bundler
|
36
39
|
puts "Bundler hack"
|
37
40
|
require 'pry-byebug'
|
@@ -56,13 +59,13 @@ module Brick
|
|
56
59
|
define_method(:require) do |name|
|
57
60
|
puts name if name.to_s.include?('cucu')
|
58
61
|
if (require_override = ::Brick::Util.instance_variable_get(:@_require_overrides)[name])
|
59
|
-
extension, folder_matcher,
|
62
|
+
extension, folder_matcher, replacements, autoload_symbol = require_override
|
60
63
|
patched_filename = "/patched_#{name.tr('/', '_')}#{extension}"
|
61
64
|
if $LOADED_FEATURES.find { |f| f.end_with?(patched_filename) }
|
62
65
|
false
|
63
66
|
else
|
64
67
|
is_replaced = false
|
65
|
-
if (replacement_path = ::Brick::Util._write_patched(folder_matcher, name, extension, ::Brick::Util._custom_require_dir, patched_filename,
|
68
|
+
if (replacement_path = ::Brick::Util._write_patched(folder_matcher, name, extension, ::Brick::Util._custom_require_dir, patched_filename, replacements))
|
66
69
|
is_replaced = Kernel.send(:orig_require, replacement_path)
|
67
70
|
elsif replacement_path.nil?
|
68
71
|
puts "Couldn't find #{name} to require it!"
|
@@ -75,7 +78,7 @@ module Brick
|
|
75
78
|
end
|
76
79
|
end
|
77
80
|
end
|
78
|
-
require_overrides[module_filename] = [extension, folder_matcher,
|
81
|
+
require_overrides[module_filename] = [extension, folder_matcher, replacements, autoload_symbol]
|
79
82
|
end
|
80
83
|
end
|
81
84
|
|
@@ -94,7 +97,7 @@ module Brick
|
|
94
97
|
|
95
98
|
# Returns the full path to the replaced filename, or
|
96
99
|
# false if the file already exists, and nil if it was unable to write anything.
|
97
|
-
def self._write_patched(folder_matcher, name, extension, dir, patched_filename,
|
100
|
+
def self._write_patched(folder_matcher, name, extension, dir, patched_filename, replacements)
|
98
101
|
# See if our replacement file might already exist for some reason
|
99
102
|
name = +"/#{name}" unless name.start_with?('/')
|
100
103
|
name << extension unless name.end_with?(extension)
|
@@ -111,9 +114,13 @@ module Brick
|
|
111
114
|
break if path.include?(folder_matcher) && (orig_as = File.open(orig_path))
|
112
115
|
end
|
113
116
|
puts [folder_matcher, name].inspect
|
114
|
-
if (
|
115
|
-
File.open(replacement_path, 'w') do |
|
116
|
-
|
117
|
+
if (updated_text = orig_as&.read)
|
118
|
+
File.open(replacement_path, 'w') do |replaced_file|
|
119
|
+
replacements = [replacements] unless replacements.first.is_a?(Array)
|
120
|
+
replacements.each do |search_text, replacement_text|
|
121
|
+
updated_text.gsub!(search_text, replacement_text)
|
122
|
+
end
|
123
|
+
num_written = replaced_file.write(updated_text)
|
117
124
|
end
|
118
125
|
orig_as.close
|
119
126
|
end
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'brick/compatibility'
|
4
4
|
|
5
|
-
# Allow ActiveRecord 4.
|
5
|
+
# Allow ActiveRecord 4.2.7 and older to work with newer Ruby (>= 2.4) by avoiding a "stack level too deep"
|
6
6
|
# error when ActiveSupport tries to smarten up Numeric by messing with Fixnum and Bignum at the end of:
|
7
7
|
# activesupport-4.0.13/lib/active_support/core_ext/numeric/conversions.rb
|
8
|
-
if ActiveRecord.version < ::Gem::Version.new('4.2') &&
|
8
|
+
if ActiveRecord.version < ::Gem::Version.new('4.2.8') &&
|
9
9
|
ActiveRecord.version > ::Gem::Version.new('3.2') &&
|
10
10
|
Object.const_defined?('Integer') && Integer.superclass.name == 'Numeric'
|
11
11
|
class OurFixnum < Integer; end
|
@@ -31,25 +31,78 @@ if (ruby_version = ::Gem::Version.new(RUBY_VERSION)) >= ::Gem::Version.new('2.7'
|
|
31
31
|
# Remove circular reference for "now"
|
32
32
|
::Brick::Util._patch_require(
|
33
33
|
'active_support/values/time_zone.rb', '/activesupport',
|
34
|
-
' def parse(str, now=now)',
|
35
|
-
|
34
|
+
[' def parse(str, now=now)',
|
35
|
+
' def parse(str, now=now())']
|
36
36
|
)
|
37
37
|
# Remove circular reference for "reflection" for ActiveRecord 3.1
|
38
38
|
if ActiveRecord.version >= ::Gem::Version.new('3.1')
|
39
39
|
::Brick::Util._patch_require(
|
40
40
|
'active_record/associations/has_many_association.rb', '/activerecord',
|
41
|
-
'reflection = reflection)',
|
42
|
-
|
41
|
+
['reflection = reflection)',
|
42
|
+
'reflection = reflection())'],
|
43
43
|
:HasManyAssociation # Make sure the path for this guy is available to be autoloaded
|
44
44
|
)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
# Add left_outer_join! to Associations::JoinDependency and Relation::QueryMethods
|
49
|
+
if ActiveRecord.version < ::Gem::Version.new('5')
|
50
|
+
is_add_left_outer_join = true
|
51
|
+
::Brick::Util._patch_require(
|
52
|
+
'active_record/associations/join_dependency.rb', '/activerecord', # /associations
|
53
|
+
["def join_constraints(outer_joins)
|
54
|
+
joins = join_root.children.flat_map { |child|
|
55
|
+
make_inner_joins join_root, child
|
56
|
+
}",
|
57
|
+
"def join_constraints(outer_joins, join_type)
|
58
|
+
joins = join_root.children.flat_map { |child|
|
59
|
+
|
60
|
+
if join_type == Arel::Nodes::OuterJoin
|
61
|
+
make_left_outer_joins join_root, child
|
62
|
+
else
|
63
|
+
make_inner_joins join_root, child
|
64
|
+
end
|
65
|
+
}"],
|
66
|
+
:JoinDependency # This one is in an "eager_autoload do" -- so how to handle it?
|
67
|
+
)
|
68
|
+
|
69
|
+
# Three changes all in the same file, query_methods.rb:
|
70
|
+
::Brick::Util._patch_require(
|
71
|
+
'active_record/relation/query_methods.rb', '/activerecord',
|
72
|
+
[
|
73
|
+
# Change 1 - Line 904
|
74
|
+
['build_joins(arel, joins_values.flatten) unless joins_values.empty?',
|
75
|
+
"build_joins(arel, joins_values.flatten) unless joins_values.empty?
|
76
|
+
build_left_outer_joins(arel, left_outer_joins_values.flatten) unless left_outer_joins_values.empty?"
|
77
|
+
],
|
78
|
+
# Change 2 - Line 992
|
79
|
+
["raise 'unknown class: %s' % join.class.name
|
80
|
+
end
|
81
|
+
end",
|
82
|
+
"raise 'unknown class: %s' % join.class.name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
build_join_query(manager, buckets, Arel::Nodes::InnerJoin)
|
87
|
+
end
|
88
|
+
|
89
|
+
def build_join_query(manager, buckets, join_type)"
|
90
|
+
],
|
91
|
+
# Change 3 - Line 1012
|
92
|
+
['join_infos = join_dependency.join_constraints stashed_association_joins',
|
93
|
+
'join_infos = join_dependency.join_constraints stashed_association_joins, join_type'
|
94
|
+
]
|
95
|
+
],
|
96
|
+
:QueryMethods
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
48
101
|
# puts ::Brick::Util._patch_require(
|
49
102
|
# 'cucumber/cli/options.rb', '/cucumber/cli/options', # /cli/options
|
50
|
-
# ' def extract_environment_variables',
|
51
|
-
#
|
52
|
-
# puts 'Patch test!'"
|
103
|
+
# [' def extract_environment_variables',
|
104
|
+
# " def extract_environment_variables\n
|
105
|
+
# puts 'Patch test!'"]
|
53
106
|
# ).inspect
|
54
107
|
|
55
108
|
# An ActiveRecord extension that uses INFORMATION_SCHEMA views to reflect on all
|
@@ -295,10 +348,11 @@ module Brick
|
|
295
348
|
|
296
349
|
relations = ::Brick.relations
|
297
350
|
if (ars = ::Brick.config.additional_references) || ::Brick.config.polymorphics
|
351
|
+
is_optional = ActiveRecord.version >= ::Gem::Version.new('5.0')
|
298
352
|
if ars
|
299
353
|
ars.each do |ar|
|
300
354
|
fk = ar.length < 5 ? [nil, +ar[0], ar[1], nil, +ar[2]] : [ar[0], +ar[1], ar[2], ar[3], +ar[4], ar[5]]
|
301
|
-
::Brick._add_bt_and_hm(fk, relations, false,
|
355
|
+
::Brick._add_bt_and_hm(fk, relations, false, is_optional)
|
302
356
|
end
|
303
357
|
end
|
304
358
|
if (polys = ::Brick.config.polymorphics)
|
@@ -311,7 +365,7 @@ module Brick
|
|
311
365
|
v ||= ActiveRecord::Base.execute_sql("SELECT DISTINCT #{poly}_type AS typ FROM #{table_name}").each_with_object([]) { |result, s| s << result['typ'] if result['typ'] }
|
312
366
|
v.each do |type|
|
313
367
|
if relations.key?(primary_table = type.underscore.pluralize)
|
314
|
-
::Brick._add_bt_and_hm([nil, table_name, poly, nil, primary_table, "(brick) #{table_name}_#{poly}"], relations, true,
|
368
|
+
::Brick._add_bt_and_hm([nil, table_name, poly, nil, primary_table, "(brick) #{table_name}_#{poly}"], relations, true, is_optional)
|
315
369
|
else
|
316
370
|
missing_stis[primary_table] = type unless ::Brick.existing_stis.key?(type)
|
317
371
|
end
|
@@ -414,7 +468,19 @@ end
|
|
414
468
|
|
415
469
|
require 'brick/version_number'
|
416
470
|
|
471
|
+
# Older versions of ActiveRecord would only show more serious error information from "panic" level, which is
|
472
|
+
# a level only available in Postgres 12 and older. This patch will allow older and newer versions of Postgres
|
473
|
+
# to work along with fairly old versions of Rails.
|
474
|
+
if Object.const_defined?('PG::VERSION') && ActiveRecord.version < ::Gem::Version.new('4.2.6')
|
475
|
+
::Brick::Util._patch_require(
|
476
|
+
'active_record/connection_adapters/postgresql_adapter.rb', '/activerecord', ["'panic'", "'error'"]
|
477
|
+
)
|
478
|
+
end
|
479
|
+
|
417
480
|
require 'active_record'
|
481
|
+
require 'active_record/relation'
|
482
|
+
require 'active_record/relation/query_methods' if is_add_left_outer_join
|
483
|
+
|
418
484
|
# Major compatibility fixes for ActiveRecord < 4.2
|
419
485
|
# ================================================
|
420
486
|
ActiveSupport.on_load(:active_record) do
|
@@ -633,6 +699,62 @@ ActiveSupport.on_load(:active_record) do
|
|
633
699
|
end
|
634
700
|
end
|
635
701
|
end
|
702
|
+
|
703
|
+
if is_add_left_outer_join
|
704
|
+
# Final pieces for left_outer_joins support, which was derived from this commit:
|
705
|
+
# https://github.com/rails/rails/commit/3f46ef1ddab87482b730a3f53987e04308783d8b
|
706
|
+
module Associations
|
707
|
+
class JoinDependency
|
708
|
+
def make_left_outer_joins(parent, child)
|
709
|
+
tables = child.tables
|
710
|
+
join_type = Arel::Nodes::OuterJoin
|
711
|
+
info = make_constraints parent, child, tables, join_type
|
712
|
+
|
713
|
+
[info] + child.children.flat_map { |c| make_left_outer_joins(child, c) }
|
714
|
+
end
|
715
|
+
end
|
716
|
+
end
|
717
|
+
module Querying
|
718
|
+
delegate :left_outer_joins, to: :all
|
719
|
+
end
|
720
|
+
class Relation
|
721
|
+
MULTI_VALUE_METHODS = MULTI_VALUE_METHODS + [:left_outer_joins] unless MULTI_VALUE_METHODS.include?(:left_outer_joins)
|
722
|
+
end
|
723
|
+
module QueryMethods
|
724
|
+
attr_writer :left_outer_joins_values
|
725
|
+
def left_outer_joins_values
|
726
|
+
@left_outer_joins_values ||= []
|
727
|
+
end
|
728
|
+
|
729
|
+
def left_outer_joins(*args)
|
730
|
+
check_if_method_has_arguments!(:left_outer_joins, args)
|
731
|
+
|
732
|
+
args.compact!
|
733
|
+
args.flatten!
|
734
|
+
|
735
|
+
spawn.left_outer_joins!(*args)
|
736
|
+
end
|
737
|
+
|
738
|
+
def left_outer_joins!(*args) # :nodoc:
|
739
|
+
self.left_outer_joins_values += args
|
740
|
+
self
|
741
|
+
end
|
742
|
+
|
743
|
+
def build_left_outer_joins(manager, outer_joins)
|
744
|
+
buckets = outer_joins.group_by do |join|
|
745
|
+
case join
|
746
|
+
when Hash, Symbol, Array
|
747
|
+
:association_join
|
748
|
+
else
|
749
|
+
raise ArgumentError, 'only Hash, Symbol and Array are allowed'
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
build_join_query(manager, buckets, Arel::Nodes::OuterJoin)
|
754
|
+
end
|
755
|
+
end
|
756
|
+
end
|
757
|
+
# (End of left_outer_joins support)
|
636
758
|
end
|
637
759
|
end
|
638
760
|
|
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.
|
4
|
+
version: 1.0.39
|
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-
|
11
|
+
date: 2022-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.2'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '7.
|
22
|
+
version: '7.2'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '4.2'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '7.
|
32
|
+
version: '7.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: appraisal
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|