brick 1.0.106 → 1.0.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 988907627ce35c257a41cbcf4b455ec852c9635fe4f8721c5af167e416fbb4ef
4
- data.tar.gz: c4a2fe612aa26a628f347d830197f961cf21b67c825ff968fa589e6bd342d1d7
3
+ metadata.gz: 1e9a085e3f9ba811623d8ebc5d840018348d207b6b1ecab97c066894c44c6ab0
4
+ data.tar.gz: 83f32dc71791730d7370f3375b3c19e6cc00e8062efe5b01bdb4cf5aa40b92b9
5
5
  SHA512:
6
- metadata.gz: 3488a28db2bf8f3c7f363e9b2eb4355e9de2d4021db9a39fb45656f896046bee412a7fd310861f522915bbc244af35a2707005757357ee6b9f9877ea331e7240
7
- data.tar.gz: 8a44cbbadde246520b028d0e474226cdf2d43e8d51bed023e20f21a0d5b6cc0e690a397908bcdbdb9b7ef21c7743bec64130258b859d1583b6c0facffd8edf5f
6
+ metadata.gz: dda58c12995437cb95ce60224543d64ef2ed16b0792a083e0def39e7be4569ceaaad86098f6470daf45c358db1d10a1ff350195c0c61ccd3363cbcfae0c344c2
7
+ data.tar.gz: 673a82fbbd268c4c8ba590c8eb980fe6e71a62caff710d32ff3b21b3c67927a22ec02380d5d8f8366a1dcadaece238aab3e737f92e879de9da5893dcde0251fa
data/lib/brick/config.rb CHANGED
@@ -110,6 +110,50 @@ module Brick
110
110
  @mutex.synchronize { @api_filter = proc }
111
111
  end
112
112
 
113
+ # # Proc gets called with up to 4 arguments: object_name, api_version, columns, data
114
+ # # Expected to return an array, either just of symbols defining column names, or an array with two sub-arrays, first of column detail and second of data
115
+ # def api_column_filter
116
+ # @mutex.synchronize { @api_column_filter }
117
+ # end
118
+
119
+ # def api_column_filter=(proc)
120
+ # @mutex.synchronize { @api_column_filter = proc }
121
+ # end
122
+
123
+ # Allows you to rename and exclude columns either specific to a given API version, or generally for a database object name
124
+ def api_column_renaming
125
+ @mutex.synchronize { @api_column_renaming }
126
+ end
127
+
128
+ def api_column_renaming=(renames)
129
+ @mutex.synchronize { @api_column_renaming = renames }
130
+ end
131
+
132
+ # All the view prefix things
133
+ def api_view_prefix
134
+ @mutex.synchronize { @api_view_prefix }
135
+ end
136
+
137
+ def api_view_prefix=(view_prefix)
138
+ @mutex.synchronize { @api_view_prefix = view_prefix }
139
+ end
140
+
141
+ def api_remove_view_prefix
142
+ @mutex.synchronize { @api_remove_view_prefix || @api_view_prefix }
143
+ end
144
+
145
+ def api_remove_view_prefix=(view_prefix)
146
+ @mutex.synchronize { @api_remove_view_prefix = view_prefix }
147
+ end
148
+
149
+ def api_add_view_prefix
150
+ @mutex.synchronize { @api_add_view_prefix || @api_view_prefix }
151
+ end
152
+
153
+ def api_add_view_prefix=(view_prefix)
154
+ @mutex.synchronize { @api_add_view_prefix = view_prefix }
155
+ end
156
+
113
157
  # Additional table associations to use (Think of these as virtual foreign keys perhaps)
114
158
  def additional_references
115
159
  @mutex.synchronize { @additional_references }
@@ -44,16 +44,20 @@
44
44
 
45
45
  module ActiveRecord
46
46
  class Base
47
- def self.is_brick?
48
- instance_variables.include?(:@_brick_built) && instance_variable_get(:@_brick_built)
49
- end
47
+ class << self
48
+ attr_reader :_brick_relation
50
49
 
51
- def self._assoc_names
52
- @_assoc_names ||= {}
53
- end
50
+ def is_brick?
51
+ instance_variables.include?(:@_brick_built) && instance_variable_get(:@_brick_built)
52
+ end
54
53
 
55
- def self.is_view?
56
- false
54
+ def _assoc_names
55
+ @_assoc_names ||= {}
56
+ end
57
+
58
+ def is_view?
59
+ false
60
+ end
57
61
  end
58
62
 
59
63
  def self._brick_primary_key(relation = nil)
@@ -787,21 +791,21 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
787
791
  end
788
792
  self.order_values |= final_order_by # Same as: order!(*final_order_by)
789
793
  end
790
- if (page = params['_brick_page']&.to_i)
791
- page = 1 if page < 1
792
- limit = params['_brick_page_size'] || 1000
793
- offset = (page - 1) * limit.to_i
794
- else
795
- offset = params['_brick_offset']
796
- limit = params['_brick_limit']
797
- end
794
+ # By default just 1000 rows
795
+ row_limit = params['_brick_limit'] || params['_brick_page_size'] || 1000
796
+ offset = if (page = params['_brick_page']&.to_i)
797
+ page = 1 if page < 1
798
+ (page - 1) * row_limit.to_i
799
+ else
800
+ params['_brick_offset']
801
+ end
798
802
  if offset.is_a?(Numeric) || offset&.present?
799
803
  offset = offset.to_i
800
804
  self.offset_value = offset unless offset == 0
801
- @_brick_page_num = (offset / limit.to_i) + 1 if limit&.!= 0 && (offset % limit.to_i) == 0
805
+ @_brick_page_num = (offset / row_limit.to_i) + 1 if row_limit&.!= 0 && (offset % row_limit.to_i) == 0
802
806
  end
803
- # By default just 1000 rows (Like doing: limit!(1000) but this way is compatible with AR <= 4.2)
804
- self.limit_value = limit&.to_i || 1000 unless limit.is_a?(String) && limit.empty?
807
+ # Setting limit_value= is the same as doing: limit!(1000) but this way is compatible with AR <= 4.2
808
+ self.limit_value = row_limit.to_i unless row_limit.is_a?(String) && row_limit.empty?
805
809
  wheres unless wheres.empty? # Return the specific parameters that we did use
806
810
  end
807
811
 
@@ -1261,6 +1265,7 @@ class Object
1261
1265
  # Having this separate -- will this now work out better?
1262
1266
  built_model.class_exec do
1263
1267
  @_brick_built = true
1268
+ @_brick_relation = relation
1264
1269
  hmts&.each do |hmt_fk, hms|
1265
1270
  hmt_fk = hmt_fk.tr('.', '_')
1266
1271
  hms.each do |hm|
@@ -1560,44 +1565,62 @@ class Object
1560
1565
  unless ::Brick.config.enable_api == false
1561
1566
  json['paths'] = relations.each_with_object({}) do |relation, s|
1562
1567
  next if (api_vers = relation.last.fetch(:api, nil)) &&
1563
- !(api_ver_paths = api_vers[current_api_ver])
1568
+ !(api_ver_paths = api_vers[current_api_ver] || api_vers[nil])
1564
1569
 
1565
- # binding.pry if relation.last.fetch(:isView, nil) && api_ver_paths != { relation.first => ::Brick::ALL_API_ACTIONS }
1566
- (api_ver_paths || { relation.first => ::Brick::ALL_API_ACTIONS }).each do |api_ver_path, actions|
1567
- relation_name = api_ver_path || relation.first.tr('.', '/')
1570
+ schema_tag = {}
1571
+ if (schema_name = relation.last&.fetch(:schema, nil))
1572
+ schema_tag['tags'] = [schema_name]
1573
+ end
1574
+ all_actions = relation.last.key?(:isView) ? [:index, :show] : ::Brick::ALL_API_ACTIONS
1575
+ (api_ver_paths || { relation.first => all_actions }).each do |api_ver_path, actions|
1576
+ relation_name = (api_ver_path || relation.first).tr('.', '/')
1568
1577
  table_description = relation.last[:description]
1569
- unless actions&.exclude?(:index)
1570
- s["#{current_api_root}#{relation_name}"] = {
1571
- 'get': {
1572
- 'summary': "list #{relation.first}",
1578
+
1579
+ # Column renaming / exclusions
1580
+ renamed_columns = if (column_renaming = ::Brick.find_col_renaming(api_ver_path, relation.first))
1581
+ column_renaming.each_with_object({}) do |rename, s|
1582
+ s[rename.last] = relation.last[:cols][rename.first] if rename.last
1583
+ end
1584
+ else
1585
+ relation.last[:cols]
1586
+ end
1587
+ { :index => [:get, 'list'], :create => [:post, 'create a'] }.each do |k, v|
1588
+ unless actions&.exclude?(k)
1589
+ this_resource = (s["#{current_api_root}#{relation_name}"] ||= {})
1590
+ this_resource[v.first] = {
1591
+ 'summary': "#{v[1]} #{relation.first}",
1573
1592
  'description': table_description,
1574
- 'parameters': relation.last[:cols].map do |k, v|
1575
- param = { in: 'query', 'name' => k, 'schema': { 'type': v.first } }
1576
- if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k, nil))
1593
+ 'parameters': renamed_columns.map do |k2, v2|
1594
+ param = { in: 'query', 'name': k2, 'schema': { 'type': v2.first } }
1595
+ if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k2, nil))
1577
1596
  param['description'] = col_descrip
1578
1597
  end
1579
1598
  param
1580
1599
  end,
1581
1600
  'responses': { '200': { 'description': 'successful' } }
1582
- }
1583
- }
1601
+ }.merge(schema_tag)
1602
+ end
1584
1603
  end
1585
1604
 
1586
- unless actions&.exclude?(:update)
1587
- s["#{current_api_root}#{relation_name}/{id}"] = {
1588
- 'patch': {
1589
- 'summary': "update a #{relation.first.singularize}",
1590
- 'description': table_description,
1591
- 'parameters': relation.last[:cols].reject { |k, v| Brick.config.metadata_columns.include?(k) }.map do |k, v|
1592
- param = { 'name' => k, 'schema': { 'type': v.first } }
1593
- if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k, nil))
1594
- param['description'] = col_descrip
1595
- end
1596
- param
1597
- end,
1598
- 'responses': { '200': { 'description': 'successful' } }
1599
- }
1600
- } unless relation.last.fetch(:isView, nil)
1605
+ # We have not yet implemented the #show action
1606
+ if (id_col = relation.last[:pkey]&.values&.first&.first) # ... ID-dependent stuff
1607
+ { :update => [:patch, 'update'], :destroy => [:delete, 'delete'] }.each do |k, v|
1608
+ unless actions&.exclude?(k)
1609
+ this_resource = (s["#{current_api_root}#{relation_name}/{#{id_col}}"] ||= {})
1610
+ this_resource[v.first] = {
1611
+ 'summary': "#{v[1]} a #{relation.first.singularize}",
1612
+ 'description': table_description,
1613
+ 'parameters': renamed_columns.reject { |k1, _v1| Brick.config.metadata_columns.include?(k1) }.map do |k2, v2|
1614
+ param = { 'name': k2, 'schema': { 'type': v2.first } }
1615
+ if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k2, nil))
1616
+ param['description'] = col_descrip
1617
+ end
1618
+ param
1619
+ end,
1620
+ 'responses': { '200': { 'description': 'successful' } }
1621
+ }.merge(schema_tag)
1622
+ end
1623
+ end
1601
1624
  end
1602
1625
  end # Do multiple api_ver_paths
1603
1626
  end
@@ -1633,8 +1656,38 @@ class Object
1633
1656
  join_array = ::Brick::JoinArray.new)
1634
1657
 
1635
1658
  if request.format == :js || current_api_root # Asking for JSON?
1659
+ # Apply column renaming
1636
1660
  data = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects) : ar_relation.select(selects)
1637
- render inline: { data: data }.to_json, content_type: request.format == '*/*' ? 'application/json' : request.format
1661
+ if data.present? &&
1662
+ (column_renaming = ::Brick.find_col_renaming(current_api_root, model&._brick_relation)&.select { |cr| cr.last })
1663
+ data.map!({}) do |row, s|
1664
+ column_renaming.each_with_object({}) do |rename, s|
1665
+ s[rename.last] = row[rename.first] if rename.last
1666
+ end
1667
+ end
1668
+ end
1669
+
1670
+ # %%% Still need to figure out column filtering and transformations
1671
+ # proc_result = if (column_filter = ::Brick.config.api_column_filter).is_a?(Proc)
1672
+ # object_columns = relation.last[:cols]
1673
+ # begin
1674
+ # num_args = column_filter.arity.negative? ? 5 : column_filter.arity
1675
+ # # object_name, api_version, columns, data
1676
+ # column_filter.call(*[relation.first, api_ver_path, object_columns, nil][0...num_args])
1677
+ # rescue StandardError => e
1678
+ # puts "::Brick.api_column_filter Proc error: #{e.message}"
1679
+ # end
1680
+ # end
1681
+ # columns = if (proc_result) # Proc returns up to 2 things: columns, data
1682
+ # # If it's all valid column name strings then we're just rearranging the column sequence
1683
+ # col_names = proc_result.all? { |pr| object_columns.key?(pr) } ? proc_result : proc_result.first.keys
1684
+ # col_names.each_with_object({}) { |cn, s| s[cn] = relation.last[:cols][cn] }
1685
+ # else
1686
+ # relation.last[:cols]
1687
+ # end
1688
+ # binding.pry
1689
+
1690
+ render inline: { data: data }.to_json, content_type: ['*/*', 'text/html'].include?(request.format) ? 'application/json' : request.format
1638
1691
  return
1639
1692
  end
1640
1693
 
@@ -2594,6 +2647,11 @@ module Brick
2594
2647
  end
2595
2648
  end
2596
2649
 
2650
+ def find_col_renaming(api_ver_path, relation_name)
2651
+ (column_renames = ::Brick.config.api_column_renaming&.fetch(api_ver_path, nil) ||
2652
+ ::Brick.config.api_column_renaming)&.fetch(relation_name, nil)
2653
+ end
2654
+
2597
2655
  def _class_pk(dotted_name, multitenant)
2598
2656
  Object.const_get((multitenant ? [dotted_name.split('.').last] : dotted_name.split('.')).map { |nm| "::#{nm.singularize.camelize}" }.join).primary_key
2599
2657
  end
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 106
8
+ TINY = 108
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
@@ -678,7 +678,10 @@ In config/initializers/brick.rb appropriate entries would look something like:
678
678
  ::Brick.relations.each do |k, v|
679
679
  next if !(controller_name = v.fetch(:resource, nil)&.pluralize) || existing_controllers.key?(controller_name)
680
680
 
681
- schema_name = v.fetch(:schema, nil)
681
+ object_name = k.split('.').last # Take off any first schema part
682
+ if (schema_name = v.fetch(:schema, nil))
683
+ schema_prefix = "#{schema_name}."
684
+ end
682
685
  options = {}
683
686
  options[:only] = [:index, :show] if v.key?(:isView)
684
687
  # First do the API routes if necessary
@@ -686,100 +689,125 @@ In config/initializers/brick.rb appropriate entries would look something like:
686
689
  ::Brick.api_roots&.each do |api_root|
687
690
  api_done_views = (versioned_views[api_root] ||= {})
688
691
  found = nil
692
+ test_ver_num = nil
689
693
  view_relation = nil
690
- actions = ::Brick::ALL_API_ACTIONS # By default all actions are allowed
691
694
  # If it's a view then see if there's a versioned one available by searching for resource names
692
695
  # versioned with the closest number (equal to or less than) compared with our API version number.
693
- if v.key?(:isView) && (ver = k.match(/^v([\d_]*)/).captures.first)[-1] == '_'
694
- next if api_done_views.key?(unversioned = k[ver.length + 1..-1])
695
-
696
- # # if ().length.positive? # Does it have a version number?
697
- # try_num = (ver_num = (ver = ver[1..-1].gsub('_', '.')).to_d)
698
-
699
- # Expect that the last item in the path generally holds versioning information
700
- api_ver = api_root.split('/')[-1]&.gsub('_', '.')
701
- vn_idx = api_ver.rindex(/[^\d._]/) # Position of the first numeric digit at the end of the version number
702
- # Was: .to_d
703
- test_ver_num = api_ver_num = api_ver[vn_idx + 1..-1].gsub('_', '.').to_i # Attempt to turn something like "v3" into the decimal value 3
704
- # puts [api_ver, vn_idx, api_ver_num, unversioned].inspect
705
-
706
- next if ver.to_i > api_ver_num # Don't surface any newer views in an older API
707
-
708
- test_ver_num -= 1 until test_ver_num.zero? ||
709
- (view_relation = ::Brick.relations.fetch(
710
- found = "v#{test_ver_num}_#{k[ver.length + 1..-1]}", nil
711
- ))
712
- api_done_views[unversioned] = nil # Mark that for this API version this view is done
713
-
714
- # puts "Found #{found}" if view_relation
715
- # If we haven't found "v3_view_name" or "v2_view_name" or so forth, at the last
716
- # fall back to simply looking for "v_view_name", and then finally "view_name".
717
- unversioned = "v_#{unversioned}"
718
- view_relation ||= ::Brick.relations.fetch(found = unversioned,
719
- ::Brick.relations.fetch(found = unversioned, nil)
720
- )
721
- if found && view_relation && k != unversioned
722
- # Call proc that limits which endpoints get surfaced based on version, table or view name, method (get list / get one / post / patch / delete)
723
- # Returning nil makes it do nothing, false makes it skip creating this endpoint, and an array of up to
724
- # these 3 things controls and changes the nature of the endpoint that gets built:
725
- # (updated api_name, name of different relation to route to, allowed actions such as :index, :show, :create, etc)
726
- proc_result = if (filter = ::Brick.config.api_filter).is_a?(Proc)
727
- begin
728
- filter.call(unversioned, k, actions, api_ver_num, found, test_ver_num)
729
- rescue StandardError => e
730
- puts "::Brick.api_filter Proc error: #{e.message}"
731
- end
696
+ if v.key?(:isView)
697
+ if (ver = object_name.match(/^v([\d_]*)/)&.captures&.first) && ver[-1] == '_'
698
+ core_object_name = object_name[ver.length + 1..-1]
699
+ next if api_done_views.key?(unversioned = "#{schema_prefix}v_#{core_object_name}")
700
+
701
+ # Expect that the last item in the path generally holds versioning information
702
+ api_ver = api_root.split('/')[-1]&.gsub('_', '.')
703
+ vn_idx = api_ver.rindex(/[^\d._]/) # Position of the first numeric digit at the end of the version number
704
+ # Was: .to_d
705
+ test_ver_num = api_ver_num = api_ver[vn_idx + 1..-1].gsub('_', '.').to_i # Attempt to turn something like "v3" into the decimal value 3
706
+ # puts [api_ver, vn_idx, api_ver_num, unversioned].inspect
707
+
708
+ next if ver.to_i > api_ver_num # Don't surface any newer views in an older API
709
+
710
+ test_ver_num -= 1 until test_ver_num.zero? ||
711
+ (view_relation = ::Brick.relations.fetch(
712
+ found = "#{schema_prefix}v#{test_ver_num}_#{core_object_name}", nil
713
+ ))
714
+ api_done_views[unversioned] = nil # Mark that for this API version this view is done
715
+
716
+ # puts "Found #{found}" if view_relation
717
+ # If we haven't found "v3_view_name" or "v2_view_name" or so forth, at the last
718
+ # fall back to simply looking for "v_view_name", and then finally "view_name".
719
+ no_v_prefix_name = "#{schema_prefix}#{core_object_name}"
720
+ standard_prefix = 'v_'
721
+ else
722
+ core_object_name = object_name
723
+ end
724
+ if (rvp = ::Brick.config.api_remove_view_prefix) && core_object_name.start_with?(rvp)
725
+ core_object_name.slice!(0, rvp.length)
726
+ end
727
+ no_prefix_name = "#{schema_prefix}#{core_object_name}"
728
+ unversioned = "#{schema_prefix}#{standard_prefix}#{::Brick.config.api_add_view_prefix}#{core_object_name}"
729
+ else
730
+ unversioned = k
731
+ end
732
+
733
+ view_relation ||= ::Brick.relations.fetch(found = unversioned, nil) ||
734
+ (no_v_prefix_name && ::Brick.relations.fetch(found = no_v_prefix_name, nil)) ||
735
+ (no_prefix_name && ::Brick.relations.fetch(found = no_prefix_name, nil))
736
+ if view_relation
737
+ actions = view_relation.key?(:isView) ? [:index, :show] : ::Brick::ALL_API_ACTIONS # By default all actions are allowed
738
+ # Call proc that limits which endpoints get surfaced based on version, table or view name, method (get list / get one / post / patch / delete)
739
+ # Returning nil makes it do nothing, false makes it skip creating this endpoint, and an array of up to
740
+ # these 3 things controls and changes the nature of the endpoint that gets built:
741
+ # (updated api_name, name of different relation to route to, allowed actions such as :index, :show, :create, etc)
742
+ proc_result = if (filter = ::Brick.config.api_filter).is_a?(Proc)
743
+ begin
744
+ num_args = filter.arity.negative? ? 6 : filter.arity
745
+ filter.call(*[unversioned, k, actions, api_ver_num, found, test_ver_num][0...num_args])
746
+ rescue StandardError => e
747
+ puts "::Brick.api_filter Proc error: #{e.message}"
732
748
  end
733
- # proc_result expects to receive back: [updated_api_name, to_other_relation, allowed_actions]
734
-
735
- case proc_result
736
- when NilClass
737
- # Do nothing differently than what normal behaviour would be
738
- when FalseClass # Skip implementing this endpoint
739
- view_relation[:api][api_ver_num] = nil
740
- next
741
- when Array # Did they give back an array of actions?
742
- unless proc_result.any? { |pr| ::Brick::ALL_API_ACTIONS.exclude?(pr) }
743
- proc_result = [unversioned, to_relation, proc_result]
744
- end
745
- # Otherwise don't change this array because it's probably legit
746
- when String
747
- proc_result = [proc_result] # Treat this as the surfaced api_name (path) they want to use for this endpoint
748
- else
749
- puts "::Brick.api_filter Proc warning: Unable to parse this result returned: \n #{proc_result.inspect}"
750
- proc_result = nil # Couldn't understand what in the world was returned
749
+ end
750
+ # proc_result expects to receive back: [updated_api_name, to_other_relation, allowed_actions]
751
+
752
+ case proc_result
753
+ when NilClass
754
+ # Do nothing differently than what normal behaviour would be
755
+ when FalseClass # Skip implementing this endpoint
756
+ view_relation[:api][api_ver_num] = nil
757
+ next
758
+ when Array # Did they give back an array of actions?
759
+ unless proc_result.any? { |pr| ::Brick::ALL_API_ACTIONS.exclude?(pr) }
760
+ proc_result = [unversioned, to_relation, proc_result]
751
761
  end
762
+ # Otherwise don't change this array because it's probably legit
763
+ when String
764
+ proc_result = [proc_result] # Treat this as the surfaced api_name (path) they want to use for this endpoint
765
+ else
766
+ puts "::Brick.api_filter Proc warning: Unable to parse this result returned: \n #{proc_result.inspect}"
767
+ proc_result = nil # Couldn't understand what in the world was returned
768
+ end
752
769
 
753
- if proc_result&.present?
754
- if proc_result[1] # to_other_relation
755
- if (new_view_relation = ::Brick.relations.fetch(proc_result[1], nil))
756
- k = proc_result[1] # Route this call over to this different relation
757
- view_relation = new_view_relation
758
- else
759
- puts "::Brick.api_filter Proc warning: Unable to find new suggested relation with name #{proc_result[1]} -- sticking with #{k} instead."
760
- end
761
- end
762
- if proc_result.first&.!=(k) # updated_api_name -- a different name than this relation would normally have
763
- found = proc_result.first
770
+ if proc_result&.present?
771
+ if proc_result[1] # to_other_relation
772
+ if (new_view_relation = ::Brick.relations.fetch(proc_result[1], nil))
773
+ k = proc_result[1] # Route this call over to this different relation
774
+ view_relation = new_view_relation
775
+ else
776
+ puts "::Brick.api_filter Proc warning: Unable to find new suggested relation with name #{proc_result[1]} -- sticking with #{k} instead."
764
777
  end
765
- actions &= proc_result[2] if proc_result[2] # allowed_actions
766
778
  end
779
+ if proc_result.first&.!=(k) # updated_api_name -- a different name than this relation would normally have
780
+ found = proc_result.first
781
+ end
782
+ actions &= proc_result[2] if proc_result[2] # allowed_actions
767
783
  end
768
- (view_relation[:api][api_ver_num] ||= {})[found] = actions # Add to the list of API paths this resource responds to
769
- end
770
-
771
- # view_ver_num = if (first_part = k.split('_').first) =~ /^v[\d_]+/
772
- # first_part[1..-1].gsub('_', '.').to_i
773
- # end
774
- controller_name = view_relation.fetch(:resource, nil)&.pluralize if view_relation
775
- # %%% So far we can only surface the #index action
776
- if actions.include?(:index)
777
- if schema_name
778
- full_resource = "#{schema_name}/#{found || v[:resource]}"
779
- send(:get, "#{api_root}#{full_resource}", { to: "#{controller_prefix}#{schema_name}/#{controller_name}#index" })
780
- else
781
- # Normally goes to something like: /api/v1/employees
782
- send(:get, "#{api_root}#{found || v[:resource]}", { to: "#{controller_prefix}#{controller_name}#index" })
784
+ (view_relation[:api][api_ver_num] ||= {})[unversioned] = actions # Add to the list of API paths this resource responds to
785
+
786
+ # view_ver_num = if (first_part = k.split('_').first) =~ /^v[\d_]+/
787
+ # first_part[1..-1].gsub('_', '.').to_i
788
+ # end
789
+
790
+ controller_name = if (last = view_relation.fetch(:resource, nil)&.pluralize)
791
+ "#{schema_prefix}#{last}"
792
+ else
793
+ found
794
+ end.tr('.', '/')
795
+
796
+ { :index => 'get', :create => 'post' }.each do |action, method|
797
+ if actions.include?(action)
798
+ # Normally goes to something like: /api/v1/employees
799
+ send(method, "#{api_root}#{unversioned.tr('.', '/')}", { to: "#{controller_prefix}#{controller_name}##{action}" })
800
+ end
801
+ end
802
+ # %%% We do not yet surface the #show action
803
+ if (id_col = view_relation[:pk]&.first) # ID-dependent stuff
804
+ { :update => ['put', 'patch'], :destroy => ['delete'] }.each do |action, methods|
805
+ if actions.include?(action)
806
+ methods.each do |method|
807
+ send(method, "#{api_root}#{unversioned.tr('.', '/')}/:#{id_col}", { to: "#{controller_prefix}#{controller_name}##{action}" })
808
+ end
809
+ end
810
+ end
783
811
  end
784
812
  end
785
813
  end
@@ -792,7 +820,7 @@ In config/initializers/brick.rb appropriate entries would look something like:
792
820
  else
793
821
  table_class_length = class_name.length if class_name.length > table_class_length
794
822
  tables
795
- end << [class_name, full_resource || v[:resource]]
823
+ end << [class_name, "#{schema_prefix&.tr('.', '/')}#{v[:resource]}"]
796
824
  end
797
825
 
798
826
  # Now the normal routes
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.106
4
+ version: 1.0.108
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-18 00:00:00.000000000 Z
11
+ date: 2023-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord