brick 1.0.106 → 1.0.108

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: 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