Class: ApiMaker::SelectColumnsOnCollection
- Inherits:
-
ApplicationService
- Object
- ServicePattern::Service
- ApplicationService
- ApiMaker::SelectColumnsOnCollection
- Defined in:
- app/services/api_maker/select_columns_on_collection.rb
Instance Attribute Summary collapse
-
#collection ⇒ Object
readonly
Returns the value of attribute collection.
-
#model_class ⇒ Object
readonly
Returns the value of attribute model_class.
-
#select_attributes ⇒ Object
readonly
Returns the value of attribute select_attributes.
-
#select_columns ⇒ Object
readonly
Returns the value of attribute select_columns.
-
#table_name ⇒ Object
readonly
Returns the value of attribute table_name.
Instance Method Summary collapse
-
#all_columns_to_select ⇒ Object
Selected attributes might require columns to be selected which is automatically resolved here.
-
#initialize(collection:, model_class: nil, select_attributes:, select_columns:, table_name: nil) ⇒ SelectColumnsOnCollection
constructor
A new instance of SelectColumnsOnCollection.
- #param_name ⇒ Object
- #perform ⇒ Object
-
#prepend_table_wildcard(query) ⇒ Object
Prepends ‘table_name.*’ to the query.
- #select_table_wildcard_sql ⇒ Object
- #selected_columns ⇒ Object
- #table_wildcard_prepended?(query) ⇒ Boolean
-
#validate_column_name!(column_name) ⇒ Object
Checks that the given column exists to avoid injections.
Methods inherited from ApplicationService
Constructor Details
#initialize(collection:, model_class: nil, select_attributes:, select_columns:, table_name: nil) ⇒ SelectColumnsOnCollection
Returns a new instance of SelectColumnsOnCollection.
4 5 6 7 8 9 10 11 12 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 4 def initialize(collection:, model_class: nil, select_attributes:, select_columns:, table_name: nil) raise "No collection was given" unless collection @collection = collection @model_class = model_class || collection.model @select_attributes = select_attributes&.dig(@model_class) @select_columns = select_columns @table_name = table_name || @model_class.table_name end |
Instance Attribute Details
#collection ⇒ Object (readonly)
Returns the value of attribute collection.
2 3 4 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 2 def collection @collection end |
#model_class ⇒ Object (readonly)
Returns the value of attribute model_class.
2 3 4 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 2 def model_class @model_class end |
#select_attributes ⇒ Object (readonly)
Returns the value of attribute select_attributes.
2 3 4 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 2 def select_attributes @select_attributes end |
#select_columns ⇒ Object (readonly)
Returns the value of attribute select_columns.
2 3 4 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 2 def select_columns @select_columns end |
#table_name ⇒ Object (readonly)
Returns the value of attribute table_name.
2 3 4 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 2 def table_name @table_name end |
Instance Method Details
#all_columns_to_select ⇒ Object
Selected attributes might require columns to be selected which is automatically resolved here
33 34 35 36 37 38 39 40 41 42 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 33 def all_columns_to_select required_columns = [] select_attributes&.each_value do |attribute_args| requires_columns = attribute_args.dig(:args, :requires_columns) required_columns += requires_columns if requires_columns end (selected_columns + required_columns).map(&:to_s).uniq end |
#param_name ⇒ Object
44 45 46 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 44 def param_name @param_name ||= model_class.model_name.param_key end |
#perform ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 14 def perform new_collection = collection return succeed! new_collection if new_collection.is_a?(Array) arel_table = Arel::Table.new(@table_name) if selected_columns all_columns_to_select.each do |column_name| validate_column_name!(column_name) new_collection = new_collection.select(arel_table[column_name]) end else new_collection = prepend_table_wildcard(new_collection) unless table_wildcard_prepended?(new_collection) end succeed! new_collection end |
#prepend_table_wildcard(query) ⇒ Object
Prepends ‘table_name.*’ to the query. It needs to be pre-pended in case a ‘COUNT` or another aggregate function has been added to work with `DISTINCT`.
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 49 def prepend_table_wildcard(query) old_select = query.values[:select] || [] old_select = old_select.keep_if { |select_statement| select_statement != select_table_wildcard_sql } query = query.except(:select).select(select_table_wildcard_sql) old_select.each do |select_statement| query = query.select(select_statement) end query end |
#select_table_wildcard_sql ⇒ Object
66 67 68 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 66 def select_table_wildcard_sql @select_table_wildcard_sql ||= "#{table_name}.*" end |
#selected_columns ⇒ Object
62 63 64 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 62 def selected_columns @selected_columns ||= select_columns&.dig(param_name) end |
#table_wildcard_prepended?(query) ⇒ Boolean
70 71 72 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 70 def table_wildcard_prepended?(query) query.values[:select]&.first == select_table_wildcard_sql end |
#validate_column_name!(column_name) ⇒ Object
Checks that the given column exists to avoid injections
75 76 77 |
# File 'app/services/api_maker/select_columns_on_collection.rb', line 75 def validate_column_name!(column_name) raise "Invalid column on #{model_class.name}: #{column_name}" unless model_class.columns_hash.key?(column_name.to_s) end |