Class: TypedEAV::ScalarQuery
- Inherits:
-
Object
- Object
- TypedEAV::ScalarQuery
- Defined in:
- lib/typed_eav/scalar_query.rb
Overview
SQL-backed operations over one scalar typed field.
Entity-level wrappers resolve ambient/explicit scope and preserve Rails' current relation delegation. This object owns the field-definition lookup, scalar support gate, and correlated value expression so no host or Value records are hydrated merely to order a relation.
Constant Summary collapse
- SCALAR_COLUMNS =
i[ boolean_value date_value datetime_value decimal_value integer_value string_value text_value ].freeze
- DIRECTIONS =
i[asc desc].freeze
- NULL_PLACEMENTS =
i[first last].freeze
- AGGREGATE_OPERATIONS =
i[min max sum].freeze
Instance Method Summary collapse
- #aggregate(operation:) ⇒ Object
- #count_distinct_values ⇒ Object
- #distinct_values(limit:) ⇒ Object
-
#initialize(model:, name:, scope:, parent_scope:, direction: :asc, nulls: :last) ⇒ ScalarQuery
constructor
rubocop:disable Metrics/ParameterLists -- the query object receives the resolved public API inputs explicitly.
-
#order_relation ⇒ Object
rubocop:enable Metrics/ParameterLists.
- #value_counts(limit:) ⇒ Object
Constructor Details
#initialize(model:, name:, scope:, parent_scope:, direction: :asc, nulls: :last) ⇒ ScalarQuery
rubocop:disable Metrics/ParameterLists -- the query object receives the resolved public API inputs explicitly.
25 26 27 28 29 30 31 32 |
# File 'lib/typed_eav/scalar_query.rb', line 25 def initialize(model:, name:, scope:, parent_scope:, direction: :asc, nulls: :last) @model = model @name = normalize_name(name) @direction = normalize_option(direction, DIRECTIONS, "direction") @nulls = normalize_option(nulls, NULL_PLACEMENTS, "nulls") @scope = scope @parent_scope = parent_scope end |
Instance Method Details
#aggregate(operation:) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/typed_eav/scalar_query.rb', line 90 def aggregate(operation:) raise_all_scopes! operation = normalize_option(operation, AGGREGATE_OPERATIONS, "operation") field = field_for_name column = numeric_column_for(field) relation = value_relation(field) case operation when :min then relation.minimum(column) when :max then relation.maximum(column) when :sum then relation.sum(column) end end |
#count_distinct_values ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/typed_eav/scalar_query.rb', line 62 def count_distinct_values raise_all_scopes! field = field_for_name column = scalar_column_for(field) distinct_relation = value_relation(field).select(column).distinct aliased_relation = TypedEAV::Value.from( "(#{distinct_relation.to_sql}) #{quoted_table_name("typed_eav_distinct_values")}", ) aliased_relation.count end |
#distinct_values(limit:) ⇒ Object
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/typed_eav/scalar_query.rb', line 51 def distinct_values(limit:) raise_all_scopes! field = field_for_name column = scalar_column_for(field) relation = value_relation(field).select(column).distinct relation = relation.order(Arel.sql("#{quoted_value_column(column)} ASC NULLS LAST")) relation.limit(validate_limit(limit)).pluck(column) end |
#order_relation ⇒ Object
rubocop:enable Metrics/ParameterLists
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/typed_eav/scalar_query.rb', line 35 def order_relation raise_all_scopes! field = field_for_name column = scalar_column_for(field) relation = @model.all host_table = relation.arel_table value_table = TypedEAV::Value.arel_table value_query = value_subquery(value_table, host_table, column, field) relation.reorder( Arel.sql("(#{value_query.to_sql}) #{@direction.to_s.upcase} NULLS #{@nulls.to_s.upcase}"), host_table[@model.primary_key].asc, ) end |
#value_counts(limit:) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/typed_eav/scalar_query.rb', line 75 def value_counts(limit:) raise_all_scopes! field = field_for_name column = scalar_column_for(field) count_sql = Arel.sql("COUNT(DISTINCT #{quoted_value_column(:entity_id)})") value_relation(field) .group(column) .order(Arel.sql("#{quoted_value_column(column)} ASC NULLS LAST")) .limit(validate_limit(limit)) .pluck(column, count_sql) .to_h end |