brick 1.0.142 → 1.0.144

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: 4e907aa4b41603045845a12d80de47e9ad714768929225b8bec209ddd9b92212
4
- data.tar.gz: 227137ba8ec83040eec6dbf76c3541f6438b7427c586690f7430572cdd59eb8a
3
+ metadata.gz: 6b84f681ffcc3cfbc37531e21ee68c07a27df07d0b0b63aed94d7e13fedc8ec1
4
+ data.tar.gz: b1f96b376d7c27b9a01e8025f8628efdfedff77875b089323e66bdff557a4141
5
5
  SHA512:
6
- metadata.gz: b68b20ad2ef66293dd7bdfd329c1ea341fb535e6240128beb1d5cd0dec99503ecc95b44b1adfde24f1493e4d7edb20ea61c7a4c9a1e5f6502b95c3c512261208
7
- data.tar.gz: 45722aa4054d96a858bab394a0e207e37d92ab415eb2a5832807e95d855e1c662139074bde9cf545d662a062fbe834ccd228d9595061c1dfde73990e6a3b3feb
6
+ metadata.gz: d6b2dfbd93defb98b61bd20c405657d8b3df5c9f1c4887dc37fe75a09fdcc61abc9ba15a1e9a16006487017f270d62ca1843fefeea574eb8df07fc55f136693b
7
+ data.tar.gz: 4f1d192f9420b9f8cfac9fa7d6f7f6c057d5bb0f852b8066937f79410b20005b4080b6bdec16f2e470e8fa1a9e5331fd26b64d675e1e397942ec65a371f8d977
@@ -10,6 +10,77 @@ unless ActiveRecord.respond_to?(:version)
10
10
  end
11
11
  end
12
12
 
13
+ # Allow ActiveRecord < 3.2 to work with Ruby 2.7 and later
14
+ if ::Gem::Version.new(RUBY_VERSION) >= ::Gem::Version.new('2.7')
15
+ if ActiveRecord.version < ::Gem::Version.new('3.2')
16
+ # Remove circular reference for "now"
17
+ ::Brick::Util._patch_require(
18
+ 'active_support/values/time_zone.rb', '/activesupport',
19
+ [' def parse(str, now=now)',
20
+ ' def parse(str, now=now())']
21
+ )
22
+ # Remove circular reference for "reflection" for ActiveRecord 3.1
23
+ if ActiveRecord.version >= ::Gem::Version.new('3.1')
24
+ ::Brick::Util._patch_require(
25
+ 'active_record/associations/has_many_association.rb', '/activerecord',
26
+ ['reflection = reflection)',
27
+ 'reflection = reflection())'],
28
+ :HasManyAssociation # Make sure the path for this guy is available to be autoloaded
29
+ )
30
+ end
31
+ end
32
+
33
+ unless ActiveRecord.const_defined?(:NoDatabaseError) # Generic version of NoDatabaseError for Rails <= 4.0
34
+ require 'active_model'
35
+ require 'active_record/errors'
36
+ class ::ActiveRecord::NoDatabaseError < ::ActiveRecord::StatementInvalid
37
+ end
38
+ end
39
+
40
+ # Create unfrozen route path in Rails 3.x
41
+ if ActiveRecord.version < ::Gem::Version.new('4')
42
+ # ::Brick::Util._patch_require(
43
+ # 'action_dispatch/routing/route_set.rb', '/actiondispatch',
44
+ # ["path = (script_name.blank? ? _generate_prefix(options) : script_name.chomp('/')).to_s",
45
+ # "path = (script_name.blank? ? _generate_prefix(options) : script_name.chomp('/')).to_s.dup"]
46
+ # #,
47
+ # #:RouteSet # Make sure the path for this guy is available to be autoloaded
48
+ # )
49
+ require 'action_dispatch/routing/route_set'
50
+ # This is by no means elegant -- wish the above would work instead. Here we completely replace #url_for
51
+ # only in order to add a ".dup"
52
+ ::ActionDispatch::Routing::RouteSet.class_exec do
53
+ def url_for(options)
54
+ finalize!
55
+ options = (options || {}).reverse_merge!(default_url_options)
56
+
57
+ handle_positional_args(options)
58
+
59
+ user, password = extract_authentication(options)
60
+ path_segments = options.delete(:_path_segments)
61
+ script_name = options.delete(:script_name)
62
+
63
+ # Just adding .dup on the end in order to not have a frozen string
64
+ path = (script_name.blank? ? _generate_prefix(options) : script_name.chomp('/')).to_s.dup
65
+
66
+ path_options = options.except(*::ActionDispatch::Routing::RouteSet::RESERVED_OPTIONS)
67
+ path_options = yield(path_options) if block_given?
68
+
69
+ path_addition, params = generate(path_options, path_segments || {})
70
+
71
+ path << path_addition
72
+
73
+ ActionDispatch::Http::URL.url_for(options.merge({
74
+ :path => path,
75
+ :params => params,
76
+ :user => user,
77
+ :password => password
78
+ }))
79
+ end
80
+ end
81
+ end
82
+ end
83
+
13
84
  # ActiveSupport, ActionPack, and ActionView before 4.0 didn't have #version
14
85
  require 'active_support' # Needed for Rails 4.x
15
86
  unless ActiveSupport.respond_to?(:version)
@@ -316,8 +316,10 @@ module ActiveRecord
316
316
  def self.brick_import_template
317
317
  template = constants.include?(:IMPORT_TEMPLATE) ? self::IMPORT_TEMPLATE : suggest_template(0, false, true)
318
318
  # Add the primary key to the template as being unique (unless it's already there)
319
- template[:uniques] = [pk = primary_key.to_sym]
320
- template[:all].unshift(pk) unless template[:all].include?(pk)
319
+ if primary_key
320
+ template[:uniques] = [pk = primary_key.to_sym]
321
+ template[:all].unshift(pk) unless template[:all].include?(pk)
322
+ end
321
323
  template
322
324
  end
323
325
 
@@ -458,17 +460,19 @@ module ActiveRecord
458
460
 
459
461
  module AttributeMethods
460
462
  module ClassMethods
461
- alias _brick_dangerous_attribute_method? dangerous_attribute_method?
462
- # Bypass the error "ActiveRecord::DangerousAttributeError" if this object comes from a view.
463
- # (Allows for column names such as 'attribute', 'delete', and 'update' to still work.)
464
- def dangerous_attribute_method?(name)
465
- if (is_dangerous = _brick_dangerous_attribute_method?(name)) && is_view?
466
- if column_names.include?(name.to_s)
467
- puts "WARNING: Column \"#{name}\" in view #{table_name} conflicts with a reserved ActiveRecord method name."
463
+ if respond_to?(:dangerous_attribute_method?)
464
+ alias _brick_dangerous_attribute_method? dangerous_attribute_method?
465
+ # Bypass the error "ActiveRecord::DangerousAttributeError" if this object comes from a view.
466
+ # (Allows for column names such as 'attribute', 'delete', and 'update' to still work.)
467
+ def dangerous_attribute_method?(name)
468
+ if (is_dangerous = _brick_dangerous_attribute_method?(name)) && is_view?
469
+ if column_names.include?(name.to_s)
470
+ puts "WARNING: Column \"#{name}\" in view #{table_name} conflicts with a reserved ActiveRecord method name."
471
+ end
472
+ return false
468
473
  end
469
- return false
474
+ is_dangerous
470
475
  end
471
- is_dangerous
472
476
  end
473
477
  end
474
478
  end
@@ -510,9 +514,6 @@ module ActiveRecord
510
514
  # model early in case the user wants to do an ORDER BY based on any of that.
511
515
  model._brick_calculate_bts_hms(translations, join_array) if is_add_bts || is_add_hms
512
516
 
513
- is_postgres = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
514
- is_mysql = ['Mysql2', 'Trilogy'].include?(ActiveRecord::Base.connection.adapter_name)
515
- is_mssql = ActiveRecord::Base.connection.adapter_name == 'SQLServer'
516
517
  is_distinct = nil
517
518
  wheres = {}
518
519
  params.each do |k, v|
@@ -587,7 +588,7 @@ module ActiveRecord
587
588
 
588
589
  if join_array.present?
589
590
  if ActiveRecord.version < Gem::Version.new('4.2')
590
- joins!(join_array)
591
+ self.joins_values += join_array # Same as: joins!(join_array)
591
592
  else
592
593
  left_outer_joins!(join_array)
593
594
  end
@@ -834,47 +835,27 @@ module ActiveRecord
834
835
  next
835
836
  end
836
837
 
837
- tbl_alias = if is_mysql
838
- "`b_r_#{hm.name}`"
839
- elsif is_postgres
840
- "\"b_r_#{hm.name}\""
841
- else
842
- "b_r_#{hm.name}"
843
- end
844
- pri_tbl_name = is_mysql ? "`#{pri_tbl.table_name}`" : "\"#{pri_tbl.table_name.gsub('.', '"."')}\""
845
- pri_tbl_name = if is_mysql
846
- "`#{pri_tbl.table_name}`"
847
- elsif is_postgres || is_mssql
848
- "\"#{pri_tbl.table_name.gsub('.', '"."')}\""
849
- else
850
- pri_tbl.table_name
851
- end
838
+ tbl_alias = "b_r_#{hm.name}"
852
839
  on_clause = []
853
840
  hm_selects = if fk_col.is_a?(Array) # Composite key?
854
- fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl_name}.#{pri_key[idx]}" }
841
+ fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl.table_name}.#{pri_key[idx]}" }
855
842
  fk_col.dup
856
843
  else
857
- on_clause << "#{tbl_alias}.#{fk_col} = #{pri_tbl_name}.#{pri_key}"
844
+ on_clause << "#{_br_quoted_name("#{tbl_alias}.#{fk_col}")} = #{_br_quoted_name("#{pri_tbl.table_name}.#{pri_key}")}"
858
845
  [fk_col]
859
846
  end
860
847
  if poly_type
861
848
  hm_selects << poly_type
862
- on_clause << "#{tbl_alias}.#{poly_type} = '#{name}'"
849
+ on_clause << "#{_br_quoted_name("#{tbl_alias}.#{poly_type}")} = '#{name}'"
863
850
  end
864
851
  unless from_clause
865
852
  tbl_nm = hm.macro == :has_and_belongs_to_many ? hm.join_table : hm.table_name
866
- hm_table_name = if is_mysql
867
- "`#{tbl_nm}`"
868
- elsif is_postgres || is_mssql
869
- "\"#{(tbl_nm).gsub('.', '"."')}\""
870
- else
871
- tbl_nm
872
- end
853
+ hm_table_name = _br_quoted_name(tbl_nm)
873
854
  end
874
855
  group_bys = ::Brick.is_oracle || is_mssql ? hm_selects : (1..hm_selects.length).to_a
875
856
  join_clause = "LEFT OUTER
876
- JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{count_column
877
- }) AS c_t_ FROM #{from_clause || hm_table_name} GROUP BY #{group_bys.join(', ')}) #{tbl_alias}"
857
+ JOIN (SELECT #{hm_selects.map { |s| _br_quoted_name("#{'br_t0.' if from_clause}#{s}") }.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{_br_quoted_name(count_column)
858
+ }) AS c_t_ FROM #{from_clause || hm_table_name} GROUP BY #{group_bys.join(', ')}) #{_br_quoted_name(tbl_alias)}"
878
859
  self.joins_values |= ["#{join_clause} ON #{on_clause.join(' AND ')}"] # Same as: joins!(...)
879
860
  end unless cust_col_override
880
861
  while (n = nix.pop)
@@ -922,6 +903,7 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
922
903
  s << v
923
904
  end
924
905
  else # String stuff (which defines a custom ORDER BY) just comes straight through
906
+ v = v.split('.').map { |x| "\"#{x}\"" }.join('.')
925
907
  s << v
926
908
  # Avoid "PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list" in Postgres
927
909
  selects << v if is_distinct
@@ -1013,58 +995,80 @@ Might want to add this in your brick.rb:
1013
995
  def shift_or_first(ary)
1014
996
  ary.length > 1 ? ary.shift : ary.first
1015
997
  end
998
+
999
+ def _br_quoted_name(name)
1000
+ if is_mysql
1001
+ "`#{name}`"
1002
+ elsif is_postgres || is_mssql
1003
+ "\"#{(name).gsub('.', '"."')}\""
1004
+ else
1005
+ name
1006
+ end
1007
+ end
1008
+
1009
+ def is_postgres
1010
+ @is_postgres ||= ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
1011
+ end
1012
+ def is_mysql
1013
+ @is_mysql ||= ['Mysql2', 'Trilogy'].include?(ActiveRecord::Base.connection.adapter_name)
1014
+ end
1015
+ def is_mssql
1016
+ @is_mssql ||= ActiveRecord::Base.connection.adapter_name == 'SQLServer'
1017
+ end
1016
1018
  end
1017
1019
 
1018
1020
  module Inheritance
1019
1021
  module ClassMethods
1020
1022
  private
1021
1023
 
1022
- alias _brick_find_sti_class find_sti_class
1023
- def find_sti_class(type_name)
1024
- return if type_name.is_a?(Numeric)
1024
+ if respond_to?(:find_sti_class)
1025
+ alias _brick_find_sti_class find_sti_class
1026
+ def find_sti_class(type_name)
1027
+ return if type_name.is_a?(Numeric)
1025
1028
 
1026
- if ::Brick.sti_models.key?(type_name ||= name)
1027
- ::Brick.sti_models[type_name].fetch(:base, nil) || _brick_find_sti_class(type_name)
1028
- else
1029
- # This auto-STI is more of a brute-force approach, building modules where needed
1030
- # The more graceful alternative is the overload of ActiveSupport::Dependencies#autoload_module! found below
1031
- ::Brick.sti_models[type_name] = { base: self } unless type_name.blank?
1032
- module_prefixes = type_name.split('::')
1033
- module_prefixes.unshift('') unless module_prefixes.first.blank?
1034
- module_name = module_prefixes[0..-2].join('::')
1035
- if (base_name = ::Brick.config.sti_namespace_prefixes&.fetch("#{module_name}::", nil)) ||
1036
- File.exist?(candidate_file = ::Rails.root.join('app/models' + module_prefixes.map(&:underscore).join('/') + '.rb'))
1037
- if base_name
1038
- base_name == "::#{name}" ? self : base_name.constantize
1039
- else
1040
- _brick_find_sti_class(type_name) # Find this STI class normally
1041
- end
1029
+ if ::Brick.sti_models.key?(type_name ||= name)
1030
+ ::Brick.sti_models[type_name].fetch(:base, nil) || _brick_find_sti_class(type_name)
1042
1031
  else
1043
- # Build missing prefix modules if they don't yet exist
1044
- this_module = Object
1045
- module_prefixes[1..-2].each do |module_name|
1046
- this_module = if this_module.const_defined?(module_name)
1047
- this_module.const_get(module_name)
1048
- else
1049
- this_module.const_set(module_name.to_sym, Module.new)
1050
- end
1051
- end
1052
- begin
1053
- if this_module.const_defined?(class_name = module_prefixes.last.to_sym)
1054
- this_module.const_get(class_name)
1032
+ # This auto-STI is more of a brute-force approach, building modules where needed
1033
+ # The more graceful alternative is the overload of ActiveSupport::Dependencies#autoload_module! found below
1034
+ ::Brick.sti_models[type_name] = { base: self } unless type_name.blank?
1035
+ module_prefixes = type_name.split('::')
1036
+ module_prefixes.unshift('') unless module_prefixes.first.blank?
1037
+ module_name = module_prefixes[0..-2].join('::')
1038
+ if (base_name = ::Brick.config.sti_namespace_prefixes&.fetch("#{module_name}::", nil)) ||
1039
+ File.exist?(candidate_file = ::Rails.root.join('app/models' + module_prefixes.map(&:underscore).join('/') + '.rb'))
1040
+ if base_name
1041
+ base_name == "::#{name}" ? self : base_name.constantize
1055
1042
  else
1056
- # Build STI subclass and place it into the namespace module
1057
- this_module.const_set(class_name, klass = Class.new(self))
1058
- klass
1043
+ _brick_find_sti_class(type_name) # Find this STI class normally
1059
1044
  end
1060
- rescue NameError => err
1061
- if column_names.include?(inheritance_column)
1062
- puts "Table #{table_name} has column #{inheritance_column} which ActiveRecord expects to use as its special inheritance column."
1063
- puts "Unfortunately the value \"#{type_name}\" does not seem to refer to a valid type name, greatly confusing matters. If that column is intended to be used for data and not STI, consider putting this line into your Brick initializer so that only for this table that column will not clash with ActiveRecord:"
1064
- puts " Brick.sti_type_column = { 'rails_#{inheritance_column}' => ['#{table_name}'] }"
1065
- self
1066
- else
1067
- raise
1045
+ else
1046
+ # Build missing prefix modules if they don't yet exist
1047
+ this_module = Object
1048
+ module_prefixes[1..-2].each do |module_name|
1049
+ this_module = if this_module.const_defined?(module_name)
1050
+ this_module.const_get(module_name)
1051
+ else
1052
+ this_module.const_set(module_name.to_sym, Module.new)
1053
+ end
1054
+ end
1055
+ begin
1056
+ if this_module.const_defined?(class_name = module_prefixes.last.to_sym)
1057
+ this_module.const_get(class_name)
1058
+ else
1059
+ # Build STI subclass and place it into the namespace module
1060
+ this_module.const_set(class_name, klass = Class.new(self))
1061
+ klass
1062
+ end
1063
+ rescue NameError => err
1064
+ if column_names.include?(inheritance_column)
1065
+ puts "Table #{table_name} has column #{inheritance_column} which ActiveRecord expects to use as its special inheritance column."
1066
+ puts "Unfortunately the value \"#{type_name}\" does not seem to refer to a valid type name, greatly confusing matters. If that column is intended to be used for data and not STI, consider putting this line into your Brick initializer so that only for this table that column will not clash with ActiveRecord:"
1067
+ puts " Brick.sti_type_column = { 'rails_#{inheritance_column}' => ['#{table_name}'] }"
1068
+ self
1069
+ else
1070
+ raise
1071
+ end
1068
1072
  end
1069
1073
  end
1070
1074
  end
@@ -2448,7 +2452,7 @@ end.class_exec do
2448
2452
  end
2449
2453
  relation_name = schema_name ? "#{schema_name}.#{r['relation_name']}" : r['relation_name']
2450
2454
  # Both uppers and lowers as well as underscores?
2451
- apply_double_underscore_patch if relation_name =~ /[A-Z]/ && relation_name =~ /[a-z]/ && relation_name.index('_')
2455
+ ::Brick.apply_double_underscore_patch if relation_name =~ /[A-Z]/ && relation_name =~ /[a-z]/ && relation_name.index('_')
2452
2456
  relation = relations[relation_name]
2453
2457
  relation[:isView] = true if r['table_type'] == 'VIEW'
2454
2458
  relation[:description] = r['table_description'] if r['table_description']
@@ -2497,7 +2501,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2497
2501
  relation_name.downcase!
2498
2502
  # Both uppers and lowers as well as underscores?
2499
2503
  elsif relation_name =~ /[A-Z]/ && relation_name =~ /[a-z]/ && relation_name.index('_')
2500
- apply_double_underscore_patch
2504
+ ::Brick.apply_double_underscore_patch
2501
2505
  end
2502
2506
  # Expect the default schema for SQL Server to be 'dbo'.
2503
2507
  if (::Brick.is_oracle && r[0] != schema) || (is_mssql && r[0] != 'dbo')
@@ -2524,6 +2528,15 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2524
2528
  end
2525
2529
  end
2526
2530
 
2531
+ # PostGIS adds three views which would confuse Rails if models were to be built for them.
2532
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
2533
+ if relations.key?('geography_columns') && relations.key?('geometry_columns') && relations.key?('spatial_ref_sys')
2534
+ (::Brick.config.exclude_tables ||= []) << 'geography_columns'
2535
+ ::Brick.config.exclude_tables << 'geometry_columns'
2536
+ ::Brick.config.exclude_tables << 'spatial_ref_sys'
2537
+ end
2538
+ end
2539
+
2527
2540
  # # Add unique OIDs
2528
2541
  # if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
2529
2542
  # ActiveRecord::Base.execute_sql(
@@ -2655,7 +2668,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2655
2668
  pg_catalog.col_description(
2656
2669
  ('\"' || t.table_schema || '\".\"' || t.table_name || '\"')::regclass::oid, c.ordinal_position
2657
2670
  ) AS column_description," if is_postgres}
2658
- c.column_name, c.data_type,
2671
+ c.column_name, #{is_postgres ? "CASE c.data_type WHEN 'USER-DEFINED' THEN pg_t.typname ELSE c.data_type END AS data_type" : 'c.data_type'},
2659
2672
  COALESCE(c.character_maximum_length, c.numeric_precision) AS max_length,
2660
2673
  kcu.constraint_type AS const, kcu.constraint_name AS \"key\",
2661
2674
  c.is_nullable
@@ -2676,7 +2689,11 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2676
2689
  kcu.CONSTRAINT_SCHEMA = c.table_schema
2677
2690
  AND kcu.TABLE_NAME = c.table_name
2678
2691
  AND kcu.column_name = c.column_name#{"
2679
- -- AND kcu.position_in_unique_constraint IS NULL" unless is_mssql}
2692
+ -- AND kcu.position_in_unique_constraint IS NULL" unless is_mssql}#{"
2693
+ INNER JOIN pg_catalog.pg_namespace pg_n ON pg_n.nspname = t.table_schema
2694
+ INNER JOIN pg_catalog.pg_class pg_c ON pg_n.oid = pg_c.relnamespace AND pg_c.relname = c.table_name
2695
+ INNER JOIN pg_catalog.pg_attribute pg_a ON pg_c.oid = pg_a.attrelid AND pg_a.attname = c.column_name
2696
+ INNER JOIN pg_catalog.pg_type pg_t ON pg_t.oid = pg_a.atttypid" if is_postgres}
2680
2697
  WHERE t.table_schema #{is_postgres || is_mssql ?
2681
2698
  "NOT IN ('information_schema', 'pg_catalog', 'pg_toast', 'heroku_ext',
2682
2699
  'INFORMATION_SCHEMA', 'sys')"
@@ -2698,43 +2715,6 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2698
2715
  ar_imtn = ActiveRecord.version >= ::Gem::Version.new('5.0') ? ActiveRecord::Base.internal_metadata_table_name : 'ar_internal_metadata'
2699
2716
  [ar_smtn, ar_imtn]
2700
2717
  end
2701
-
2702
- def apply_double_underscore_patch
2703
- unless @double_underscore_applied
2704
- # Same as normal #camelize and #underscore, just that double-underscores turn into a single underscore
2705
- ActiveSupport::Inflector.class_eval do
2706
- def camelize(term, uppercase_first_letter = true)
2707
- strings = term.to_s.split('__').map do |string|
2708
- # String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent.
2709
- if !uppercase_first_letter || uppercase_first_letter == :lower
2710
- string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase! || match }
2711
- else
2712
- string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize! || match }
2713
- end
2714
- string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
2715
- word = $2
2716
- substituted = inflections.acronyms[word] || word.capitalize! || word
2717
- $1 ? "::#{substituted}" : substituted
2718
- end
2719
- string
2720
- end
2721
- strings.join('_')
2722
- end
2723
-
2724
- def underscore(camel_cased_word)
2725
- return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
2726
- camel_cased_word.to_s.gsub("::", "/").split('_').map do |word|
2727
- word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
2728
- word.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { ($1 || $2) << "_" }
2729
- word.tr!("-", "_")
2730
- word.downcase!
2731
- word
2732
- end.join('__')
2733
- end
2734
- end
2735
- @double_underscore_applied = true
2736
- end
2737
- end
2738
2718
  end
2739
2719
 
2740
2720
  # ==========================================
@@ -2761,7 +2741,7 @@ module Brick
2761
2741
 
2762
2742
  class << self
2763
2743
  def _add_bt_and_hm(fk, relations, polymorphic_class = nil, is_optional = false)
2764
- bt_assoc_name = ::Brick.namify(fk[2], :downcase)
2744
+ bt_assoc_name = ::Brick.namify(fk[2].dup, :downcase)
2765
2745
  unless polymorphic_class
2766
2746
  bt_assoc_name = if bt_assoc_name.underscore.end_with?('_id')
2767
2747
  bt_assoc_name[-3] == '_' ? bt_assoc_name[0..-4] : bt_assoc_name[0..-3]
@@ -64,7 +64,7 @@ module Brick
64
64
  if lat_lng && !(lat_lng.first.zero? && lat_lng.last.zero?)
65
65
  # Create a link to this style of Google maps URL: https://www.google.com/maps/place/38.7071296+-121.2810649/@38.7071296,-121.2810649,12z
66
66
  "<a href=\"https://www.google.com/maps/place/#{lat_lng.first}+#{lat_lng.last}/@#{lat_lng.first},#{lat_lng.last},12z\" target=\"blank\">#{val}</a>"
67
- elsif val.is_a?(Numeric)
67
+ elsif val.is_a?(Numeric) && ::ActiveSupport.const_defined?(:NumberHelper)
68
68
  ::ActiveSupport::NumberHelper.number_to_delimited(val, delimiter: ',')
69
69
  else
70
70
  ::Brick::Rails::FormBuilder.hide_bcrypt(val, col_type == :xml)
@@ -685,8 +685,8 @@ window.addEventListener(\"popstate\", linkSchemas);
685
685
  rescue StandardError => e
686
686
  # Search through the routes to confirm that something might match (Devise stuff for instance, which has its own view templates),
687
687
  # and bubble the same exception (probably an ActionView::MissingTemplate) if a legitimate option is found.
688
- raise if ::Rails.application.routes.set.find { |x| args[1].include?(x.defaults[:controller]) && args[0] == x.defaults[:action] } &&
689
- ActionView.version >= ::Gem::Version.new('5.0')
688
+ raise if ActionView.version >= ::Gem::Version.new('5.0') &&
689
+ ::Rails.application.routes.set.find { |x| args[1].include?(x.defaults[:controller]) && args[0] == x.defaults[:action] }
690
690
 
691
691
  find_template_err = e
692
692
  end
@@ -1258,57 +1258,73 @@ erDiagram
1258
1258
  // Have a click on the sheets link to bring up the sign-in window. (Must happen from some kind of user click.)
1259
1259
  sheetsLink.addEventListener(\"click\", async function (evt) {
1260
1260
  evt.preventDefault();
1261
- await gapi.load(\"client\", function () {
1262
- gapi.client.init({ // Load the discovery doc to initialize the API
1263
- clientId: \"487319557829-fgj4u660igrpptdji7ev0r5hb6kh05dh.apps.googleusercontent.com\",
1264
- scope: \"https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file\",
1265
- discoveryDocs: [\"https://sheets.googleapis.com/$discovery/rest?version=v4\"]
1266
- }).then(function () {
1267
- gapi.auth2.getAuthInstance().isSignedIn.listen(updateSignInStatus);
1268
- updateSignInStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
1269
- });
1261
+ var client = google.accounts.oauth2.initTokenClient({
1262
+ client_id: \"487319557829-fgj4u660igrpptdji7ev0r5hb6kh05dh.apps.googleusercontent.com\",
1263
+ scope: \"https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file\",
1264
+ callback: updateSignInStatus
1270
1265
  });
1266
+ client.requestAccessToken();
1271
1267
  });
1272
1268
  }
1273
1269
 
1274
- async function updateSignInStatus(isSignedIn) {
1275
- if (isSignedIn) {
1276
- await gapi.client.sheets.spreadsheets.create({
1277
- properties: {
1278
- title: #{table_name.inspect},
1279
- },
1280
- sheets: [
1281
- // sheet1, sheet2, sheet3
1282
- ]
1283
- }).then(function (response) {
1284
- sheetUrl = response.result.spreadsheetUrl;
1285
- spreadsheetId = response.result.spreadsheetId;
1286
- sheetsLink.setAttribute(\"href\", sheetUrl); // response.result.spreadsheetUrl
1287
- console.log(\"x1\", sheetUrl);
1288
-
1289
- // Get JSON data
1290
- fetch(changeout(<%= #{@_brick_model._brick_index}_path(format: :js).inspect.html_safe %>, \"_brick_schema\", brickSchema)).then(function (response) {
1291
- response.json().then(function (data) {
1292
- gapi.client.sheets.spreadsheets.values.append({
1293
- spreadsheetId: spreadsheetId,
1294
- range: \"Sheet1\",
1295
- valueInputOption: \"RAW\",
1296
- insertDataOption: \"INSERT_ROWS\"
1297
- }, {
1298
- range: \"Sheet1\",
1299
- majorDimension: \"ROWS\",
1300
- values: data,
1301
- }).then(function (response2) {
1302
- // console.log(\"beefcake\", response2);
1303
- });
1270
+ async function updateSignInStatus(token) {
1271
+ await new Promise(function (resolve) {
1272
+ gapi.load(\"client\", function () {
1273
+ resolve(); // gapi client code now loaded
1274
+ });
1275
+ }).then(async function (x) {
1276
+ gapi.client.setToken(token);
1277
+ var discoveryDoc = await (await fetch(\"https://sheets.googleapis.com/$discovery/rest?version=v4\")).json();
1278
+ await gapi.client.load(discoveryDoc, function () {
1279
+ resolve(); // Spreadsheets code now loaded
1280
+ });
1281
+ });
1282
+
1283
+ await gapi.client.sheets.spreadsheets.create({
1284
+ properties: {
1285
+ title: #{table_name.inspect},
1286
+ },
1287
+ sheets: [
1288
+ // sheet1, sheet2, sheet3
1289
+ ]
1290
+ }).then(function (response) {
1291
+ sheetUrl = response.result.spreadsheetUrl;
1292
+ spreadsheetId = response.result.spreadsheetId;
1293
+ // sheetsLink.setAttribute(\"href\", sheetUrl);
1294
+
1295
+ // Get JSON data
1296
+ var jsPath = <%= #{@_brick_model._brick_index}_path(format: :js).inspect.html_safe %>;
1297
+ if (brickSchema) jsPath = changeout(jsPath, \"_brick_schema\", brickSchema);
1298
+ fetch(jsPath).then(function (response) {
1299
+ response.json().then(function (resp) {
1300
+ // Expect the first row to have field names
1301
+ var colHeaders = Object.keys(resp.data[0]);;
1302
+ var ary = [colHeaders];
1303
+ // Add all the rows
1304
+ var row;
1305
+ resp.data.forEach(function (row) {
1306
+ ary.push(Object.keys(colHeaders).reduce(function(x, y) {
1307
+ x.push(row[colHeaders[y]]); return x
1308
+ }, []));
1309
+ });
1310
+ // Send to spreadsheet
1311
+ gapi.client.sheets.spreadsheets.values.append({
1312
+ spreadsheetId: spreadsheetId,
1313
+ range: 'Sheet1',
1314
+ valueInputOption: 'RAW',
1315
+ insertDataOption: 'INSERT_ROWS',
1316
+ values: ary
1317
+ }).then(function (response2) {
1318
+ // console.log('Spreadsheet created', response2);
1304
1319
  });
1305
1320
  });
1306
1321
  });
1307
1322
  window.open(sheetUrl, '_blank');
1308
- }
1323
+ });
1309
1324
  }
1310
1325
  </script>
1311
- <script async defer src=\"https://apis.google.com/js/api.js\" onload=\"gapiLoaded()\"></script>
1326
+ <script src=\"https://apis.google.com/js/api.js\"></script>
1327
+ <script async defer src=\"https://accounts.google.com/gsi/client\" onload=\"gapiLoaded()\"></script>
1312
1328
  "
1313
1329
  end # DutyFree data export and import
1314
1330
  # %%% Instead of our current "for Janet Leverling (Employee)" kind of link we previously had this code that did a "where x = 123" thing:
@@ -1723,7 +1739,10 @@ end
1723
1739
  case collection
1724
1740
  when ActiveRecord::Relation # has_many (which comes in as a CollectionProxy) or a has_one#{
1725
1741
  poly_fix}
1726
- collection2, descrip_cols = collection.brick_list
1742
+ collection2, descrip_cols = begin
1743
+ collection.brick_list
1744
+ rescue
1745
+ end
1727
1746
  when ActiveRecord::Base # Object from a has_one :through
1728
1747
  collection2 = [collection]
1729
1748
  else # We get an array back when AR < 4.2
@@ -41,7 +41,7 @@ module Brick::Rails::FormBuilder
41
41
  col&.type
42
42
  end
43
43
  case (col_type ||= col&.sql_type)
44
- when :string, :text
44
+ when :string, :text, :citext
45
45
  if ::Brick::Rails::FormBuilder.is_bcrypt?(val) # || .readonly?
46
46
  is_revert = false
47
47
  out << ::Brick::Rails::FormBuilder.hide_bcrypt(val, nil, 1000)
data/lib/brick/util.rb CHANGED
@@ -32,9 +32,6 @@ module Brick
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
38
35
  elsif is_bundler
39
36
  puts "Bundler hack"
40
37
  require 'pry-byebug'
@@ -52,12 +49,11 @@ module Brick
52
49
  # then required in place of the original.
53
50
 
54
51
  Kernel.module_exec do
55
- # class << self
56
52
  alias_method :orig_require, :require
57
- # end
58
53
  # To be most faithful to Ruby's normal behaviour, this should look like a public singleton
59
54
  define_method(:require) do |name|
60
- puts name if name.to_s.include?('cucu')
55
+ # %%% Can get a message such as "ActionDispatch::Routing is not missing constant RouteSet! (NameError)"
56
+ # binding.pry if name.start_with?('action_dispatch/routing/route_') # || name == 'active_support/values/time_zone'
61
57
  if (require_override = ::Brick::Util.instance_variable_get(:@_require_overrides)[name])
62
58
  extension, folder_matcher, replacements, autoload_symbol = require_override
63
59
  patched_filename = "/patched_#{name.tr('/', '_')}#{extension}"
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 142
8
+ TINY = 144
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,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'brick/compatibility'
4
+ ruby_version = ::Gem::Version.new(RUBY_VERSION)
4
5
 
5
6
  # Allow ActiveRecord 4.2.7 and older to work with newer Ruby (>= 2.4) by avoiding a "stack level too deep"
6
7
  # error when ActiveSupport tries to smarten up Numeric by messing with Fixnum and Bignum at the end of:
@@ -25,37 +26,6 @@ end
25
26
 
26
27
  require 'brick/util'
27
28
 
28
- # Allow ActiveRecord < 3.2 to work with Ruby 2.7 and later
29
- if (is_ruby_2_7 = (ruby_version = ::Gem::Version.new(RUBY_VERSION)) >= ::Gem::Version.new('2.7'))
30
- if ActiveRecord.version < ::Gem::Version.new('3.2')
31
- # Remove circular reference for "now"
32
- ::Brick::Util._patch_require(
33
- 'active_support/values/time_zone.rb', '/activesupport',
34
- [' def parse(str, now=now)',
35
- ' def parse(str, now=now())']
36
- )
37
- # Remove circular reference for "reflection" for ActiveRecord 3.1
38
- if ActiveRecord.version >= ::Gem::Version.new('3.1')
39
- ::Brick::Util._patch_require(
40
- 'active_record/associations/has_many_association.rb', '/activerecord',
41
- ['reflection = reflection)',
42
- 'reflection = reflection())'],
43
- :HasManyAssociation # Make sure the path for this guy is available to be autoloaded
44
- )
45
- end
46
- end
47
-
48
- # # Create unfrozen route path in Rails 3.2
49
- # if ActiveRecord.version < ::Gem::Version.new('4')
50
- # ::Brick::Util._patch_require(
51
- # 'action_dispatch/routing/route_set.rb', '/actiondispatch',
52
- # ["script_name.chomp('/')).to_s",
53
- # "script_name.chomp('/')).to_s.dup"],
54
- # :RouteSet # Make sure the path for this guy is available to be autoloaded
55
- # )
56
- # end
57
- end
58
-
59
29
  # Add left_outer_joins! to Associations::JoinDependency and Relation::QueryMethods
60
30
  if ActiveRecord.version >= ::Gem::Version.new('4') && ActiveRecord.version < ::Gem::Version.new('5')
61
31
  ::Brick::Util._patch_require(
@@ -163,7 +133,8 @@ module Brick
163
133
 
164
134
  # All tables and views (what Postgres calls "relations" including column and foreign key info)
165
135
  def relations
166
- return {} if ::ActiveRecord::Base.connection_handler.connection_pool_list.blank?
136
+ return {} if (ch = ::ActiveRecord::Base.connection_handler).respond_to?(:connection_pool_list) &&
137
+ ch.connection_pool_list.blank?
167
138
 
168
139
  # Key our list of relations for this connection off of the connection pool's object_id
169
140
  (@relations ||= {})[ActiveRecord::Base.connection_pool.object_id] ||= Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = {} } }
@@ -724,6 +695,44 @@ In config/initializers/brick.rb appropriate entries would look something like:
724
695
  end
725
696
  [klass, sti_type, found]
726
697
  end
698
+
699
+ def apply_double_underscore_patch
700
+ unless @double_underscore_applied
701
+ # Same as normal #camelize and #underscore, just that double-underscores turn into a single underscore
702
+ ActiveSupport::Inflector.class_eval do
703
+ def camelize(term, uppercase_first_letter = true)
704
+ strings = term.to_s.split('__').map do |string|
705
+ # String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent.
706
+ if !uppercase_first_letter || uppercase_first_letter == :lower
707
+ string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase! || match }
708
+ else
709
+ string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize! || match }
710
+ end
711
+ string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
712
+ word = $2
713
+ substituted = inflections.acronyms[word] || word.capitalize! || word
714
+ $1 ? "::#{substituted}" : substituted
715
+ end
716
+ string
717
+ end
718
+ strings.join('_')
719
+ end
720
+
721
+ def underscore(camel_cased_word)
722
+ return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
723
+ regex = inflections.respond_to?(:acronyms_underscore_regex) ? inflections.acronyms_underscore_regex : inflections.acronym_regex
724
+ camel_cased_word.to_s.gsub('::', '/').split('_').map do |word|
725
+ word.gsub!(regex) { "#{$1 && '_' }#{$2.downcase}" }
726
+ word.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { ($1 || $2) << '_' }
727
+ word.tr!('-', '_')
728
+ word.downcase!
729
+ word
730
+ end.join('__')
731
+ end
732
+ end
733
+ @double_underscore_applied = true
734
+ end
735
+ end
727
736
  end
728
737
 
729
738
  module RouteSet
@@ -946,20 +955,22 @@ In config/initializers/brick.rb appropriate entries would look something like:
946
955
  end
947
956
  end
948
957
 
949
- if ::Brick.config.add_status && (status_as = "#{controller_prefix.tr('/', '_')}brick_status".to_sym)
950
- (
951
- !(status_route = instance_variable_get(:@set).named_routes.find { |route| route.first == status_as }&.last) ||
952
- !status_route.ast.to_s.include?("/#{controller_prefix}brick_status/")
953
- )
954
- get("/#{controller_prefix}brick_status", to: 'brick_gem#status', as: status_as.to_s)
955
- end
958
+ if (named_routes = instance_variable_get(:@set).named_routes).respond_to?(:find)
959
+ if ::Brick.config.add_status && (status_as = "#{controller_prefix.tr('/', '_')}brick_status".to_sym)
960
+ (
961
+ !(status_route = instance_variable_get(:@set).named_routes.find { |route| route.first == status_as }&.last) ||
962
+ !status_route.ast.to_s.include?("/#{controller_prefix}brick_status/")
963
+ )
964
+ get("/#{controller_prefix}brick_status", to: 'brick_gem#status', as: status_as.to_s)
965
+ end
956
966
 
957
- if ::Brick.config.add_orphans && (orphans_as = "#{controller_prefix.tr('/', '_')}brick_orphans".to_sym)
958
- (
959
- !(orphans_route = instance_variable_get(:@set).named_routes.find { |route| route.first == orphans_as }&.last) ||
960
- !orphans_route.ast.to_s.include?("/#{controller_prefix}brick_orphans/")
961
- )
962
- get("/#{controller_prefix}brick_orphans", to: 'brick_gem#orphans', as: 'brick_orphans')
967
+ if ::Brick.config.add_orphans && (orphans_as = "#{controller_prefix.tr('/', '_')}brick_orphans".to_sym)
968
+ (
969
+ !(orphans_route = instance_variable_get(:@set).named_routes.find { |route| route.first == orphans_as }&.last) ||
970
+ !orphans_route.ast.to_s.include?("/#{controller_prefix}brick_orphans/")
971
+ )
972
+ get("/#{controller_prefix}brick_orphans", to: 'brick_gem#orphans', as: 'brick_orphans')
973
+ end
963
974
  end
964
975
 
965
976
  if instance_variable_get(:@set).named_routes.names.exclude?(:brick_crosstab)
@@ -1030,7 +1041,11 @@ require 'brick/version_number'
1030
1041
  if (is_postgres = (Object.const_defined?('PG::VERSION') || Gem::Specification.find_all_by_name('pg').present?)) &&
1031
1042
  ActiveRecord.version < ::Gem::Version.new('4.2.6')
1032
1043
  ::Brick::Util._patch_require(
1033
- 'active_record/connection_adapters/postgresql_adapter.rb', '/activerecord', ["'panic'", "'error'"]
1044
+ 'active_record/connection_adapters/postgresql_adapter.rb', '/activerecord', [
1045
+ ["'panic'", "'error'"],
1046
+ # ActiveRecord < 3.2.13 uses the pg_attrdef.adsrc column, but it's missing in Postgres 12 and later, so we need to use pg_get_expr(d.adbin, d.adrelid).
1047
+ [', d.adsrc,', ', pg_get_expr(d.adbin, d.adrelid),']
1048
+ ]
1034
1049
  )
1035
1050
  end
1036
1051
 
@@ -1317,8 +1332,8 @@ ActiveSupport.on_load(:active_record) do
1317
1332
  end
1318
1333
  # rubocop:enable Lint/ConstantDefinitionInBlock
1319
1334
 
1320
- arsc = ::ActiveRecord::StatementCache
1321
- if is_ruby_2_7 && arsc.respond_to?(:create) &&
1335
+ if ruby_version >= ::Gem::Version.new('2.7') && ::ActiveRecord.const_defined?(:StatementCache) &&
1336
+ (arsc = ::ActiveRecord::StatementCache).respond_to?(:create) &&
1322
1337
  (params = arsc.method(:create).parameters).length == 2 && params.last == [:opt, :block]
1323
1338
  arsc.class_exec do
1324
1339
  def self.create(connection, callable = nil, &block)
@@ -1423,14 +1438,18 @@ ActiveSupport.on_load(:active_record) do
1423
1438
  elsif araat.respond_to?(:create) # Rails 4.1 and 4.2
1424
1439
  @alias_tracker = araat.create(base.connection, joins)
1425
1440
  @alias_tracker.aliased_table_for(base, base.table_name) # Updates the count for base.table_name to 1
1426
- else # Rails 4.0
1441
+ else # Rails <= 4.0
1427
1442
  is_rails_4 = true
1428
1443
  @base_klass = base
1429
1444
  @table_joins = joins
1430
1445
  @join_parts = [JoinBase.new(base)]
1431
1446
  @associations = {}
1432
1447
  @reflections = []
1433
- @alias_tracker = araat.new(base.connection, joins)
1448
+ @alias_tracker = if araat.instance_method(:initialize).parameters.length == 2 # Rails > 3.2.8
1449
+ araat.new(base.connection, joins)
1450
+ else
1451
+ araat.new(joins)
1452
+ end
1434
1453
  @alias_tracker.aliased_name_for(base.table_name) # Updates the count for base.table_name to 1
1435
1454
  tree = build(associations)
1436
1455
  end
@@ -1441,7 +1460,7 @@ ActiveSupport.on_load(:active_record) do
1441
1460
  if (relation = associations.instance_variable_get(:@relation))
1442
1461
  tree.instance_variable_set(:@relation, relation)
1443
1462
  end
1444
- return if is_rails_4 # Rails 4.0 doesn't know about the rest
1463
+ return if is_rails_4 # Rails <= 4.0 doesn't know about the rest
1445
1464
 
1446
1465
  @join_root = JoinBase.new base, build(tree, base)
1447
1466
  @join_root.children.each { |child| construct_tables! @join_root, child }
@@ -1618,7 +1637,7 @@ module ActiveRecord
1618
1637
  _brick_build_join_query(manager, buckets, *args) # , **kwargs)
1619
1638
  end
1620
1639
 
1621
- else # elsif private_instance_methods.include?(:select_association_list)
1640
+ elsif private_instance_methods.include?(:select_association_list)
1622
1641
  alias _brick_select_association_list select_association_list
1623
1642
  def select_association_list(associations, stashed_joins = nil)
1624
1643
  result = _brick_select_association_list(associations, stashed_joins)
@@ -137,7 +137,8 @@ module Brick
137
137
  fringe.each do |tbl|
138
138
  next unless (relation = ::Brick.relations.fetch(tbl, nil))&.fetch(:cols, nil)&.present?
139
139
 
140
- pkey_cols = (rpk = relation[:pkey].values.flatten) & (arpk = [ApplicationRecord.primary_key].flatten.sort)
140
+ ar_base = Object.const_defined?(:ApplicationRecord) ? ApplicationRecord : Class.new(ActiveRecord::Base)
141
+ pkey_cols = (rpk = relation[:pkey].values.flatten) & (arpk = [ar_base.primary_key].flatten.sort)
141
142
  # In case things aren't as standard
142
143
  if pkey_cols.empty?
143
144
  pkey_cols = if rpk.empty? && relation[:cols][arpk.first]&.first == key_type
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.142
4
+ version: 1.0.144
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-05-17 00:00:00.000000000 Z
11
+ date: 2023-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: 3.1.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: 3.1.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: fancy_gets
29
29
  requirement: !ruby/object:Gem::Requirement