brick 1.0.97 → 1.0.99

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: c257a0a65807fa87a13d722f3cc30c38d51bde571a070df53f4277fc6db8b7ba
4
- data.tar.gz: 74d7690a968fab671d9e9e8ac92e41885ceb44a700fd1cb293f3b79af819e463
3
+ metadata.gz: 431e2aee4c3c199095d8475eeedcc46bd95e86a47c51623e3cea7fbbde59edcd
4
+ data.tar.gz: 32144a9a9ab6ec60ef297f27ae73e35cc891e5f9462b9beae4e7a0534ab77135
5
5
  SHA512:
6
- metadata.gz: 4337faa80a6f0d9c1dadcb3271aea14ec54bb91e72cd7eead7e59c860557f828ac073cab3768feaa2db2f664d63b1604bd8f8e0d53c64621b1fcf5cc041057d9
7
- data.tar.gz: 541cade2070bd0a79b21dd7155df700b2739084ae81eaa02709f9e00164f956e62e8342330a78496c4b5fbf351cac9ea40483d3cdc32c1fb1dbe8d7e34499d2d
6
+ metadata.gz: f471bc993d97e92deae3c03e6cac9db0e350e72bd070afe5bcde1d0ca18d650b546db0d018a101009e429e9870a7e2c5e566f980c9e5b1319bc18873271c5550
7
+ data.tar.gz: 95f128f0f2a29cf0d1af1b5001eae27885b7e11ce23194e4a4da0141a0bfc059edd1917036f4addf1ee2aa4b69f763962e821ca31f9473048a6934dbecd8518e
@@ -398,15 +398,27 @@ module ActiveRecord
398
398
  # Links from ActiveRecord association pathing names over to real table correlation names
399
399
  # that get chosen when the AREL AST tree is walked.
400
400
  def brick_links
401
- @brick_links ||= {}
401
+ @brick_links ||= { '' => table_name }
402
402
  end
403
403
 
404
404
  def brick_select(params, selects = [], order_by = nil, translations = {}, join_array = ::Brick::JoinArray.new)
405
405
  is_add_bts = is_add_hms = true
406
406
 
407
- # Build out cust_cols, bt_descrip and hm_counts now so that they are available on the
408
- # model early in case the user wants to do an ORDER BY based on any of that.
409
- model._brick_calculate_bts_hms(translations, join_array) if is_add_bts || is_add_hms
407
+ if selects.empty?
408
+ # Build out cust_cols, bt_descrip and hm_counts now so that they are available on the
409
+ # model early in case the user wants to do an ORDER BY based on any of that.
410
+ model._brick_calculate_bts_hms(translations, join_array) if is_add_bts || is_add_hms
411
+ else
412
+ is_api = true
413
+ # If there are any provided selects, treat them as API columns and build them as cust_cols since they
414
+ # can be built using DSL.
415
+ # false = not polymorphic, and true = yes -- please emit_dsl
416
+ selects.each do |api_col|
417
+ pieces, my_dsl = brick_parse_dsl(join_array, [], translations, false, "[#{api_col}]", true)
418
+ _br_cust_cols[api_col.tr('.', '_')] = [pieces, my_dsl]
419
+ end
420
+ selects.clear # Now these have become custom columns
421
+ end
410
422
 
411
423
  is_postgres = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
412
424
  is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2'
@@ -414,7 +426,7 @@ module ActiveRecord
414
426
  is_distinct = nil
415
427
  wheres = {}
416
428
  params.each do |k, v|
417
- next if ['_brick_schema', '_brick_order', 'controller', 'action'].include?(k)
429
+ next if ['_brick_schema', '_brick_order', '_brick_api', 'controller', 'action'].include?(k)
418
430
 
419
431
  if (where_col = (ks = k.split('.')).last)[-1] == '!'
420
432
  where_col = where_col[0..-2]
@@ -436,11 +448,14 @@ module ActiveRecord
436
448
 
437
449
  # %%% Skip the metadata columns
438
450
  if selects.empty? # Default to all columns
451
+ id_parts = (id_col = klass.primary_key).is_a?(Array) ? id_col : [id_col]
439
452
  tbl_no_schema = table.name.split('.').last
440
453
  # %%% Have once gotten this error with MSSQL referring to http://localhost:3000/warehouse/cold_room_temperatures__archive
441
454
  # ActiveRecord::StatementInvalid (TinyTds::Error: DBPROCESS is dead or not enabled)
442
455
  # Relevant info here: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/402
443
456
  columns.each do |col|
457
+ next if is_api && id_parts.exclude?(col.name) # Only keep the ID columns if this is an API request
458
+
444
459
  col_alias = " AS #{col.name}_" if (col_name = col.name) == 'class'
445
460
  selects << if is_mysql
446
461
  "`#{tbl_no_schema}`.`#{col_name}`#{col_alias}"
@@ -490,22 +505,28 @@ module ActiveRecord
490
505
  # binding.pry
491
506
  next
492
507
  end
493
-
494
508
  key_klass = nil
495
509
  key_tbl_name = nil
496
510
  dest_pk = nil
497
511
  key_alias = nil
498
512
  cc.first.each do |cc_part|
499
- dest_klass = cc_part[0..-2].inject(klass) { |kl, cc_part_term| kl.reflect_on_association(cc_part_term).klass }
513
+ dest_klass = cc_part[0..-2].inject(klass) do |kl, cc_part_term|
514
+ # %%% Clear column info properly so we can do multiple subsequent requests
515
+ # binding.pry unless kl.reflect_on_association(cc_part_term)
516
+ kl.reflect_on_association(cc_part_term)&.klass || klass
517
+ end
500
518
  tbl_name = rel_dupe.brick_links[cc_part[0..-2].map(&:to_s).join('.')]
501
519
  # Deal with the conflict if there are two parts in the custom column named the same,
502
520
  # "category.name" and "product.name" for instance will end up with aliases of "name"
503
521
  # and "product__name".
504
- cc_part_idx = cc_part.length - 1
505
- while cc_part_idx > 0 &&
506
- (col_alias = "br_cc_#{k}__#{cc_part[cc_part_idx..-1].map(&:to_s).join('__')}") &&
507
- used_col_aliases.key?(col_alias)
508
- cc_part_idx -= 1
522
+ if (cc_part_idx = cc_part.length - 1).zero?
523
+ col_alias = "br_cc_#{k}__#{table_name.tr('.', '_')}"
524
+ else
525
+ while cc_part_idx > 0 &&
526
+ (col_alias = "br_cc_#{k}__#{cc_part[cc_part_idx..-1].map(&:to_s).join('__').tr('.', '_')}") &&
527
+ used_col_aliases.key?(col_alias)
528
+ cc_part_idx -= 1
529
+ end
509
530
  end
510
531
  used_col_aliases[col_alias] = nil
511
532
  # Set up custom column links by preparing key_klass and key_alias
@@ -540,7 +561,11 @@ module ActiveRecord
540
561
  tbl_name = "\"#{tbl_name}\"" if ::Brick.is_oracle && rel_dupe.brick_links.values.include?(tbl_name)
541
562
  field_tbl_name = nil
542
563
  v1.map { |x| [x[0..-2].map(&:to_s).join('.'), x.last] }.each_with_index do |sel_col, idx|
543
- field_tbl_name = rel_dupe.brick_links[sel_col.first].split('.').last
564
+ # %%% Strangely in Rails 7.1 on a slower system then very rarely brick_link comes back nil...
565
+ brick_link = rel_dupe.brick_links[sel_col.first]
566
+ field_tbl_name = brick_link&.split('.')&.last ||
567
+ # ... so here's a best-effort guess for what the table name might be.
568
+ rel_dupe.klass.reflect_on_association(sel_col.first).klass.table_name
544
569
  # If it's Oracle, quote any AREL aliases that had been applied
545
570
  field_tbl_name = "\"#{field_tbl_name}\"" if ::Brick.is_oracle && rel_dupe.brick_links.values.include?(field_tbl_name)
546
571
 
@@ -825,80 +850,9 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
825
850
  end
826
851
 
827
852
  if Object.const_defined?('ActionView')
853
+ require 'brick/frameworks/rails/form_tags'
828
854
  module ActionView::Helpers::FormTagHelper
829
- def link_to_brick(*args, **kwargs)
830
- return unless ::Brick.config.mode == :on
831
-
832
- text = (args.first.is_a?(String) && args.first) || args[1]
833
- klass_or_obj = ((args.first.is_a?(ActiveRecord::Relation) ||
834
- args.first.is_a?(ActiveRecord::Base) ||
835
- args.first.is_a?(Class)) &&
836
- args.first) ||
837
- @_brick_model
838
- # If not provided, do a best-effort to automatically determine the resource class or object
839
- filter_parts = []
840
- klass_or_obj ||= begin
841
- klass, sti_type = ::Brick.ctrl_to_klass(controller_path)
842
- if klass
843
- type_col = klass.inheritance_column # Usually 'type'
844
- filter_parts << "#{type_col}=#{sti_type}" if sti_type && klass.column_names.include?(type_col)
845
- path_params = request.path_parameters.dup
846
- path_params.delete(:controller)
847
- path_params.delete(:action)
848
- pk = (klass.primary_key || ActiveRecord::Base.primary_key).to_sym
849
- # Used to also have this but it's a bit too permissive to identify a primary key: (path_params.length == 1 && path_params.values.first) ||
850
- if ((id = (path_params[pk] || path_params[:id] || path_params["#{klass.name.underscore}_id".to_sym])) && (obj = klass.find_by(pk => id))) ||
851
- (['show', 'edit', 'update', 'destroy'].include?(action_name) && (obj = klass.first))
852
- obj
853
- else
854
- # %%% If there is a HMT that refers to some ___id then try to identify an appropriate filter
855
- # %%% If there is a polymorphic association that might relate to stuff in the path_params,
856
- # try to identify an appropriate ___able_id and ___able_type filter
857
- ((klass.column_names - [pk.to_s]) & path_params.keys.map(&:to_s)).each do |path_param|
858
- filter_parts << "#{path_param}=#{path_params[path_param.to_sym]}"
859
- end
860
- klass
861
- end
862
- end
863
- rescue
864
- end
865
- if klass_or_obj
866
- if klass_or_obj.is_a?(ActiveRecord::Relation)
867
- klass_or_obj.where_values_hash.each do |whr|
868
- filter_parts << "#{whr.first}=#{whr.last}" if whr.last && !whr.last.is_a?(Array)
869
- end
870
- klass_or_obj = klass_or_obj.klass
871
- type_col = klass_or_obj.inheritance_column
872
- if klass_or_obj.column_names.include?(type_col) && klass_or_obj.name != klass_or_obj.base_class.name
873
- filter_parts << "#{type_col}=#{klass_or_obj.name}"
874
- end
875
- elsif klass_or_obj.is_a?(ActiveRecord::Base) && klass_or_obj.new_record?
876
- klass_or_obj = klass_or_obj.class
877
- end
878
- filter = "?#{filter_parts.join('&')}" if filter_parts.present?
879
- if (klass_or_obj&.is_a?(Class) && klass_or_obj < ActiveRecord::Base) ||
880
- (klass_or_obj&.is_a?(ActiveRecord::Base) && klass_or_obj.new_record? && (klass_or_obj = klass_or_obj.class))
881
- lt_args = [text || "Index for #{klass_or_obj.name.pluralize}",
882
- "#{send("#{klass_or_obj._brick_index}_path")}#{filter}"]
883
- else
884
- # If there are multiple incoming parameters then last one is probably the actual ID, and first few might be some nested tree of stuff leading up to it
885
- lt_args = [text || "Show this #{klass_or_obj.class.name}",
886
- "#{send("#{klass_or_obj.class._brick_index(:singular)}_path", klass_or_obj)}#{filter}"]
887
- end
888
- link_to(*lt_args, **kwargs)
889
- else
890
- # puts "Warning: link_to_brick could not find a class for \"#{controller_path}\" -- consider setting @_brick_model within that controller."
891
- # if (hits = res_names.keys & instance_variables.map { |v| v.to_s[1..-1] }).present?
892
- links = instance_variables.each_with_object([]) do |name, s|
893
- iv_name = name.to_s[1..-1]
894
- case (val = instance_variable_get(name))
895
- when ActiveRecord::Relation, ActiveRecord::Base
896
- s << link_to_brick(val, iv_name) if val
897
- end
898
- end
899
- links.join(' &nbsp; ').html_safe
900
- end
901
- end
855
+ include ::Brick::Rails::FormTags
902
856
  end
903
857
  end
904
858
 
@@ -1002,6 +956,7 @@ Module.class_exec do
1002
956
  end
1003
957
  class_name = ::Brick.namify(requested)
1004
958
  relations = ::Brick.relations
959
+ # CONTROLLER
1005
960
  result = if ::Brick.enable_controllers? &&
1006
961
  is_controller && (plural_class_name = class_name[0..-11]).length.positive?
1007
962
  # Otherwise now it's up to us to fill in the gaps
@@ -1020,6 +975,8 @@ Module.class_exec do
1020
975
  # if it's a controller and no match or a model doesn't really use the same table name, eager load all models and try to find a model class of the right name.
1021
976
  Object.send(:build_controller, self, class_name, plural_class_name, model, relations)
1022
977
  end
978
+
979
+ # MODULE
1023
980
  elsif (::Brick.enable_models? || ::Brick.enable_controllers?) && # Schema match?
1024
981
  base_module == Object && # %%% This works for Person::Person -- but also limits us to not being able to allow more than one level of namespacing
1025
982
  (schema_name = [(singular_table_name = class_name.underscore),
@@ -1036,6 +993,50 @@ Module.class_exec do
1036
993
 
1037
994
  [built_module, "module #{schema_name}; end\n"]
1038
995
  # # %%% Perhaps an option to use the first module just as schema, and additional modules as namespace with a table name prefix applied
996
+
997
+ # AVO Resource
998
+ elsif base_module == Object && Object.const_defined?('Avo') && requested.end_with?('Resource') &&
999
+ ['MotorResource'].exclude?(requested) # Expect that anything called MotorResource could be from that administrative gem
1000
+ if (model = Object.const_get(requested[0..-9]))
1001
+ require 'generators/avo/resource_generator'
1002
+ field_generator = Generators::Avo::ResourceGenerator.new([''])
1003
+ field_generator.instance_variable_set(:@model, model)
1004
+ fields = field_generator.send(:generate_fields).split("\n")
1005
+ .each_with_object([]) do |f, s|
1006
+ if (f = f.strip).start_with?('field ')
1007
+ f = f[6..-1].split(',')
1008
+ s << [f.first[1..-1].to_sym, [f[1][1..-1].split(': :').map(&:to_sym)].to_h]
1009
+ end
1010
+ end
1011
+ built_resource = Class.new(Avo::BaseResource) do |new_resource_class|
1012
+ self.model_class = model
1013
+ self.title = :brick_descrip
1014
+ self.includes = []
1015
+ if (!model.is_view? && mod_pk = model.primary_key)
1016
+ field((mod_pk.is_a?(Array) ? mod_pk.first : mod_pk).to_sym, { as: :id })
1017
+ end
1018
+ # Create a call such as: field :name, as: :text
1019
+ fields.each do |f|
1020
+ # Add proper types if this is a polymorphic belongs_to
1021
+ if f.last == { as: :belongs_to } &&
1022
+ (fk = ::Brick.relations[model.table_name][:fks].find { |k, v| v[:assoc_name] == f.first.to_s }) &&
1023
+ fk.last.fetch(:polymorphic, nil)
1024
+ poly_types = fk.last.fetch(:inverse_table, nil)&.each_with_object([]) do |poly_table, s|
1025
+ s << Object.const_get(::Brick.relations[poly_table][:class_name])
1026
+ end
1027
+ if poly_types.present?
1028
+ f.last[:polymorphic_as] = f.first
1029
+ f.last[:types] = poly_types
1030
+ end
1031
+ end
1032
+ self.send(:field, *f)
1033
+ end
1034
+ end
1035
+ Object.const_set(requested.to_sym, built_resource)
1036
+ [built_resource, nil]
1037
+ end
1038
+
1039
+ # MODEL
1039
1040
  elsif ::Brick.enable_models?
1040
1041
  # Custom inheritable Brick base model?
1041
1042
  class_name = (inheritable_name = class_name)[5..-1] if class_name.start_with?('Brick')
@@ -1392,19 +1393,24 @@ class Object
1392
1393
  when Symbol
1393
1394
  order_tbl[order_default] || order_default
1394
1395
  else
1395
- pk.map(&:to_sym) # If it's not a custom ORDER BY, just use the key
1396
+ pk.map { |part| "#{table_name}.#{part}"}.join(', ') # If it's not a custom ORDER BY, just use the key
1396
1397
  end
1397
1398
  end
1398
1399
 
1399
1400
  def build_controller(namespace, class_name, plural_class_name, model, relations)
1401
+ if (is_avo = (namespace.name == 'Avo' && Object.const_defined?('Avo')))
1402
+ # Basic Avo functionality is available via its own generic controller.
1403
+ # (More information on https://docs.avohq.io/2.0/controllers.html)
1404
+ controller_base = Avo::ResourcesController
1405
+ end
1400
1406
  table_name = ActiveSupport::Inflector.underscore(plural_class_name)
1401
1407
  singular_table_name = ActiveSupport::Inflector.singularize(table_name)
1402
1408
  pk = model&._brick_primary_key(relations.fetch(table_name, nil))
1403
1409
  is_postgres = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
1404
1410
  is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2'
1405
1411
 
1406
- code = +"class #{class_name} < ApplicationController\n"
1407
- built_controller = Class.new(ActionController::Base) do |new_controller_class|
1412
+ code = +"class #{class_name} < #{controller_base&.name || 'ApplicationController'}\n"
1413
+ built_controller = Class.new(controller_base || ActionController::Base) do |new_controller_class|
1408
1414
  (namespace || Object).const_set(class_name.to_sym, new_controller_class)
1409
1415
 
1410
1416
  # Brick-specific pages
@@ -1501,118 +1507,129 @@ class Object
1501
1507
  end
1502
1508
 
1503
1509
  self.protect_from_forgery unless: -> { self.request.format.js? }
1504
- self.define_method :index do
1505
- if (is_openapi || request.env['REQUEST_PATH'].start_with?(::Brick.api_root)) &&
1506
- !params&.key?('_brick_schema') &&
1507
- (referrer_params = request.env['HTTP_REFERER']&.split('?')&.last&.split('&')&.map { |x| x.split('=') }).present?
1508
- if params
1509
- referrer_params.each { |k, v| params.send(:parameters)[k] = v }
1510
- else
1511
- api_params = referrer_params&.to_h
1510
+ unless is_avo
1511
+ self.define_method :index do
1512
+ if (is_openapi || request.env['REQUEST_PATH'].start_with?(::Brick.api_root)) &&
1513
+ !params&.key?('_brick_schema') &&
1514
+ (referrer_params = request.env['HTTP_REFERER']&.split('?')&.last&.split('&')&.map { |x| x.split('=') }).present?
1515
+ if params
1516
+ referrer_params.each { |k, v| params.send(:parameters)[k] = v }
1517
+ else
1518
+ api_params = referrer_params&.to_h
1519
+ end
1512
1520
  end
1513
- end
1514
- _schema, @_is_show_schema_list = ::Brick.set_db_schema(params || api_params)
1515
-
1516
- if is_openapi
1517
- json = { 'openapi': '3.0.1', 'info': { 'title': Rswag::Ui.config.config_object[:urls].last&.fetch(:name, 'API documentation'), 'version': ::Brick.config.api_version },
1518
- 'servers': [
1519
- { 'url': '{scheme}://{defaultHost}', 'variables': {
1520
- 'scheme': { 'default': request.env['rack.url_scheme'] },
1521
- 'defaultHost': { 'default': request.env['HTTP_HOST'] }
1522
- } }
1523
- ]
1524
- }
1525
- json['paths'] = relations.inject({}) do |s, relation|
1526
- unless ::Brick.config.enable_api == false
1527
- table_description = relation.last[:description]
1528
- s["#{::Brick.config.api_root}#{relation.first.tr('.', '/')}"] = {
1529
- 'get': {
1530
- 'summary': "list #{relation.first}",
1531
- 'description': table_description,
1532
- 'parameters': relation.last[:cols].map do |k, v|
1533
- param = { 'name' => k, 'schema': { 'type': v.first } }
1534
- if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k, nil))
1535
- param['description'] = col_descrip
1536
- end
1537
- param
1538
- end,
1539
- 'responses': { '200': { 'description': 'successful' } }
1540
- }
1541
- }
1542
-
1543
- s["#{::Brick.config.api_root}#{relation.first.tr('.', '/')}/{id}"] = {
1544
- 'patch': {
1545
- 'summary': "update a #{relation.first.singularize}",
1546
- 'description': table_description,
1547
- 'parameters': relation.last[:cols].reject { |k, v| Brick.config.metadata_columns.include?(k) }.map do |k, v|
1548
- param = { 'name' => k, 'schema': { 'type': v.first } }
1549
- if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k, nil))
1550
- param['description'] = col_descrip
1551
- end
1552
- param
1553
- end,
1554
- 'responses': { '200': { 'description': 'successful' } }
1521
+ _schema, @_is_show_schema_list = ::Brick.set_db_schema(params || api_params)
1522
+
1523
+ if is_openapi
1524
+ json = { 'openapi': '3.0.1', 'info': { 'title': Rswag::Ui.config.config_object[:urls].last&.fetch(:name, 'API documentation'), 'version': ::Brick.config.api_version },
1525
+ 'servers': [
1526
+ { 'url': '{scheme}://{defaultHost}', 'variables': {
1527
+ 'scheme': { 'default': request.env['rack.url_scheme'] },
1528
+ 'defaultHost': { 'default': request.env['HTTP_HOST'] }
1529
+ } }
1530
+ ]
1531
+ }
1532
+ json['paths'] = relations.inject({}) do |s, relation|
1533
+ unless ::Brick.config.enable_api == false
1534
+ table_description = relation.last[:description]
1535
+ s["#{::Brick.config.api_root}#{relation.first.tr('.', '/')}"] = {
1536
+ 'get': {
1537
+ 'summary': "list #{relation.first}",
1538
+ 'description': table_description,
1539
+ 'parameters': relation.last[:cols].map do |k, v|
1540
+ param = { 'name' => k, 'schema': { 'type': v.first } }
1541
+ if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k, nil))
1542
+ param['description'] = col_descrip
1543
+ end
1544
+ param
1545
+ end,
1546
+ 'responses': { '200': { 'description': 'successful' } }
1547
+ }
1555
1548
  }
1556
- } unless relation.last.fetch(:isView, nil)
1557
- s
1549
+
1550
+ s["#{::Brick.config.api_root}#{relation.first.tr('.', '/')}/{id}"] = {
1551
+ 'patch': {
1552
+ 'summary': "update a #{relation.first.singularize}",
1553
+ 'description': table_description,
1554
+ 'parameters': relation.last[:cols].reject { |k, v| Brick.config.metadata_columns.include?(k) }.map do |k, v|
1555
+ param = { 'name' => k, 'schema': { 'type': v.first } }
1556
+ if (col_descrip = relation.last.fetch(:col_descrips, nil)&.fetch(k, nil))
1557
+ param['description'] = col_descrip
1558
+ end
1559
+ param
1560
+ end,
1561
+ 'responses': { '200': { 'description': 'successful' } }
1562
+ }
1563
+ } unless relation.last.fetch(:isView, nil)
1564
+ s
1565
+ end
1558
1566
  end
1567
+ render inline: json.to_json, content_type: request.format
1568
+ return
1559
1569
  end
1560
- render inline: json.to_json, content_type: request.format
1561
- return
1562
- end
1563
1570
 
1564
- if request.format == :csv # Asking for a template?
1565
- require 'csv'
1566
- exported_csv = CSV.generate(force_quotes: false) do |csv_out|
1567
- model.df_export(model.brick_import_template).each { |row| csv_out << row }
1571
+ if request.format == :csv # Asking for a template?
1572
+ require 'csv'
1573
+ exported_csv = CSV.generate(force_quotes: false) do |csv_out|
1574
+ model.df_export(model.brick_import_template).each { |row| csv_out << row }
1575
+ end
1576
+ render inline: exported_csv, content_type: request.format
1577
+ return
1578
+ elsif request.format == :js || request.path.start_with?('/api/') # Asking for JSON?
1579
+ data = (model.is_view? || !Object.const_defined?('DutyFree')) ? model.limit(1000) : model.df_export(model.brick_import_template)
1580
+ render inline: data.to_json, content_type: request.format == '*/*' ? 'application/json' : request.format
1581
+ return
1568
1582
  end
1569
- render inline: exported_csv, content_type: request.format
1570
- return
1571
- elsif request.format == :js || request.path.start_with?('/api/') # Asking for JSON?
1572
- data = (model.is_view? || !Object.const_defined?('DutyFree')) ? model.limit(1000) : model.df_export(model.brick_import_template)
1573
- render inline: data.to_json, content_type: request.format == '*/*' ? 'application/json' : request.format
1574
- return
1575
- end
1576
1583
 
1577
- # Normal (not swagger or CSV) request
1578
-
1579
- # %%% Allow params to define which columns to use for order_by
1580
- # Overriding the default by providing a querystring param?
1581
- ordering = params['_brick_order']&.split(',')&.map(&:to_sym) || Object.send(:default_ordering, table_name, pk)
1582
- order_by, _ = model._brick_calculate_ordering(ordering, true) # Don't do the txt part
1583
-
1584
- ar_relation = ActiveRecord.version < Gem::Version.new('4') ? model.preload : model.all
1585
- @_brick_params = ar_relation.brick_select(params, (selects = []), order_by,
1586
- translations = {},
1587
- join_array = ::Brick::JoinArray.new)
1588
- # %%% Add custom HM count columns
1589
- # %%% What happens when the PK is composite?
1590
- counts = model._br_hm_counts.each_with_object([]) do |v, s|
1591
- s << if is_mysql
1592
- "`b_r_#{v.first}`.c_t_ AS \"b_r_#{v.first}_ct\""
1593
- elsif is_postgres
1594
- "\"b_r_#{v.first}\".c_t_ AS \"b_r_#{v.first}_ct\""
1595
- else
1596
- "b_r_#{v.first}.c_t_ AS \"b_r_#{v.first}_ct\""
1597
- end
1598
- end
1599
- ar_select = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects, *counts) : ar_relation.select(selects + counts)
1600
- instance_variable_set("@#{table_name.pluralize}".to_sym, ar_select)
1601
- if namespace && (idx = lookup_context.prefixes.index(table_name))
1602
- lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
1603
- end
1604
- @_brick_excl = session[:_brick_exclude]&.split(',')&.each_with_object([]) do |excl, s|
1605
- if (excl_parts = excl.split('.')).first == table_name
1606
- s << excl_parts.last
1584
+ # Normal (not swagger or CSV) request
1585
+
1586
+ # %%% Allow params to define which columns to use for order_by
1587
+ # Overriding the default by providing a querystring param?
1588
+ ordering = params['_brick_order']&.split(',')&.map(&:to_sym) || Object.send(:default_ordering, table_name, pk)
1589
+ order_by, _ = model._brick_calculate_ordering(ordering, true) # Don't do the txt part
1590
+
1591
+ ar_relation = ActiveRecord.version < Gem::Version.new('4') ? model.preload : model.all
1592
+
1593
+ if (cc = params['_brick_api']&.split(','))
1594
+ is_api = true
1595
+ selects = cc
1596
+ counts = [] # No need for any extra HM count columns
1597
+ model._br_cust_cols.clear
1598
+ end
1599
+
1600
+ @_brick_params = ar_relation.brick_select(params, (selects ||= []), order_by,
1601
+ translations = {},
1602
+ join_array = ::Brick::JoinArray.new)
1603
+ # %%% Add custom HM count columns
1604
+ # %%% What happens when the PK is composite?
1605
+ counts = model._br_hm_counts.each_with_object([]) do |v, s|
1606
+ s << if is_mysql
1607
+ "`b_r_#{v.first}`.c_t_ AS \"b_r_#{v.first}_ct\""
1608
+ elsif is_postgres
1609
+ "\"b_r_#{v.first}\".c_t_ AS \"b_r_#{v.first}_ct\""
1610
+ else
1611
+ "b_r_#{v.first}.c_t_ AS \"b_r_#{v.first}_ct\""
1612
+ end
1613
+ end
1614
+
1615
+ ar_select = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects, *counts) : ar_relation.select(selects + counts)
1616
+ instance_variable_set("@#{table_name.pluralize}".to_sym, ar_select)
1617
+ if namespace && (idx = lookup_context.prefixes.index(table_name))
1618
+ lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
1619
+ end
1620
+ @_brick_excl = session[:_brick_exclude]&.split(',')&.each_with_object([]) do |excl, s|
1621
+ if (excl_parts = excl.split('.')).first == table_name
1622
+ s << excl_parts.last
1623
+ end
1607
1624
  end
1608
- end
1609
- @_brick_bt_descrip = model._br_bt_descrip
1610
- @_brick_hm_counts = model._br_hm_counts
1611
- @_brick_join_array = join_array
1612
- @_brick_erd = params['_brick_erd']&.to_i
1625
+ @_brick_bt_descrip = model._br_bt_descrip
1626
+ @_brick_hm_counts = model._br_hm_counts
1627
+ @_brick_join_array = join_array
1628
+ @_brick_erd = params['_brick_erd']&.to_i
1629
+ end
1613
1630
  end
1614
1631
 
1615
- unless is_openapi
1632
+ unless is_openapi || is_avo
1616
1633
  _, order_by_txt = model._brick_calculate_ordering(default_ordering(table_name, pk)) if pk
1617
1634
  code << " def index\n"
1618
1635
  code << " @#{table_name.pluralize} = #{model.name}#{pk&.present? ? ".order(#{order_by_txt.join(', ')})" : '.all'}\n"
@@ -3,7 +3,7 @@
3
3
  module Brick
4
4
  module Rails
5
5
  # Extensions to rails controllers. Provides convenient ways to pass certain
6
- # information to the model layer, with `controller_info` and `whodunnit`.
6
+ # information to the model layer, with `controller_info`.
7
7
  # Also includes a convenient on/off switch,
8
8
  # `brick_enabled_for_controller`.
9
9
  module Controller