class ActiveRecordExtended::QueryMethods::Select::SelectHelper
Constants
- AGGREGATE_ONE_LINERS
Public Class Methods
new(scope)
click to toggle source
# File lib/active_record_extended/query_methods/select.rb, line 12 def initialize(scope) @scope = scope end
Public Instance Methods
build_foster_select(*args)
click to toggle source
# File lib/active_record_extended/query_methods/select.rb, line 16 def build_foster_select(*args) flatten_safely(args).each do |select_arg| case select_arg when String, Symbol select!(select_arg) when Hash select_arg.each_pair do |alias_name, options_or_column| case options_or_column when Array process_array!(options_or_column, alias_name) when Hash process_hash!(options_or_column, alias_name) else select!(options_or_column, alias_name) end end end end end
Private Instance Methods
hash_to_dot_notation(column)
click to toggle source
Turn a hash chain into a query statement: Example: hash_to_dot_notation
(table_name: :col_name) #=> “table_name.col_name”
# File lib/active_record_extended/query_methods/select.rb, line 65 def hash_to_dot_notation(column) case column when Hash, Array column.to_a.flat_map { |col| hash_to_dot_notation(col) }.join(".") when String, Symbol /^([[:alpha:]]+)$/.match?(column.to_s) ? double_quote(column) : column else column end end
process_array!(array_of_options, alias_name)
click to toggle source
Assumes that the first element in the array is the source/target column. Example process_array_options!(, :my_alias_name)
#=> SELECT ([:col_name:]) AS "my_alias_name", ...
# File lib/active_record_extended/query_methods/select.rb, line 42 def process_array!(array_of_options, alias_name) options = array_of_options.detect { |opts| opts.is_a?(Hash) } query = { __select_statement: array_of_options.first } query.merge!(options) unless options.nil? process_hash!(query, alias_name) end
process_hash!(hash_of_options, alias_name)
click to toggle source
Processes options that come in as Hash elements Examples: process_hash_options!({ memberships: :price, cast_with: :agg_array_distinct }, :past_purchases)
#=> SELECT (ARRAY_AGG(DISTINCT members.price)) AS past_purchases, ...
# File lib/active_record_extended/query_methods/select.rb, line 53 def process_hash!(hash_of_options, alias_name) enforced_options = { cast_with: hash_of_options[:cast_with], order_by: hash_of_options[:order_by], distinct: !(!hash_of_options[:distinct]) } query_statement = hash_to_dot_notation(hash_of_options[:__select_statement] || hash_of_options.first) select!(query_statement, alias_name, **enforced_options) end
select!(query, alias_name = nil, **options)
click to toggle source
Add's select statement values to the current relation, select statement lists
# File lib/active_record_extended/query_methods/select.rb, line 77 def select!(query, alias_name = nil, **options) pipe_cte_with!(query) @scope._select!(to_casted_query(query, alias_name, **options)) end
to_casted_query(query, alias_name, **options)
click to toggle source
Wraps the query with the requested query method Example:
to_casted_query("memberships.cost", :total_revenue, :sum) #=> SELECT (SUM(memberships.cost)) AS total_revenue
# File lib/active_record_extended/query_methods/select.rb, line 86 def to_casted_query(query, alias_name, **options) cast_with = options[:cast_with].to_s.downcase order_expr = order_by_expression(options[:order_by]) distinct = cast_with.chomp!("_distinct") || options[:distinct] # account for [:agg_name:]_distinct case cast_with when "array", "true" wrap_with_array(query, alias_name) when AGGREGATE_ONE_LINERS expr = to_sql_array(query) { |value| group_when_needed(value) } casted_query = ::Arel::Nodes::AggregateFunctionName.new(cast_with, expr, distinct).order_by(order_expr) nested_alias_escape(casted_query, alias_name) else alias_name.presence ? nested_alias_escape(query, alias_name) : query end end