Class: ActiveRecord::Refined::AST::StringAggregate

Inherits:
Node
  • Object
show all
Includes:
Predications, Windowing
Defined in:
lib/active_record/refined/ast.rb

Overview

The strings of a group joined into one, a separator between: string_agg(:title, ", "), with .order for the order they are joined in. Every family has it under a name of its own with the ORDER BY in a place of its own, and Arel has no node for an ORDER BY inside a call, so the dialect writes the call. A NULL is passed over as by any aggregate, so the CASE that stands in for FILTER means the same here and is not refused as the JSON aggregates' is.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Windowing

#over

Methods included from Predications

#!=, #!~, #<, #<=, #==, #=~, #>, #>=, #between?, #bury, #casecmp?, #contains?, #dig, #dig_text, #distinct_from?, #end_with?, #except, #false?, #ilike?, #in?, #include?, #intersect?, #key?, #keys, #like?, #member?, #not_between?, #not_distinct_from?, #not_false?, #not_ilike?, #not_in?, #not_like?, #not_null?, #not_true?, #null?, #start_with?, #subset?, #superset?, #true?, #when

Methods inherited from Node

#as, #asc, #collate, #desc

Constructor Details

#initialize(operand, separator, orders: [], condition: nil) ⇒ StringAggregate

Returns a new instance of StringAggregate.



1732
1733
1734
1735
1736
1737
1738
1739
1740
# File 'lib/active_record/refined/ast.rb', line 1732

def initialize(operand, separator, orders: [], condition: nil)
  unless separator.is_a?(::String)
    raise ArgumentError, "#{separator.inspect} is not a String separator"
  end
  @operand = operand
  @separator = separator
  @orders = orders
  @condition = condition
end

Instance Attribute Details

#conditionObject (readonly)

Returns the value of attribute condition.



1730
1731
1732
# File 'lib/active_record/refined/ast.rb', line 1730

def condition
  @condition
end

#operandObject (readonly)

Returns the value of attribute operand.



1730
1731
1732
# File 'lib/active_record/refined/ast.rb', line 1730

def operand
  @operand
end

#ordersObject (readonly)

Returns the value of attribute orders.



1730
1731
1732
# File 'lib/active_record/refined/ast.rb', line 1730

def orders
  @orders
end

#separatorObject (readonly)

Returns the value of attribute separator.



1730
1731
1732
# File 'lib/active_record/refined/ast.rb', line 1730

def separator
  @separator
end

Instance Method Details

#check_window(model) ⇒ Object



1757
1758
1759
# File 'lib/active_record/refined/ast.rb', line 1757

def check_window(model)
  Dialect.for(model).check_string_aggregate_window(model)
end

#filter(condition = nil, &block) ⇒ AST::StringAggregate

FILTER (WHERE condition), as Aggregate#filter.



1752
1753
1754
1755
# File 'lib/active_record/refined/ast.rb', line 1752

def filter(condition = nil, &block)
  StringAggregate.new(operand, separator, orders: orders,
                      condition: Case.argument(:filter, condition, block))
end

#order(*exprs) ⇒ AST::StringAggregate

The order the strings are joined in: columns, or orderings such as :title.desc.

Returns:

Raises:

  • (ArgumentError)


1745
1746
1747
1748
# File 'lib/active_record/refined/ast.rb', line 1745

def order(*exprs)
  raise ArgumentError, "order needs an expression" if exprs.empty?
  StringAggregate.new(operand, separator, orders: orders + exprs, condition: condition)
end

#to_arel(table, model) ⇒ Object



1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
# File 'lib/active_record/refined/ast.rb', line 1761

def to_arel(table, model)
  dialect = Dialect.for(model)
  kept = condition && !dialect.filter_supported? ?
    Case.new.when(condition).then(operand) : operand
  call = dialect.string_agg(
    to_arel_argument(kept, table, model), separator,
    orders.map { |expr| to_arel_operand(expr, table, model) },
    string_operand?(model), model)
  return call unless condition && dialect.filter_supported?
  Arel::Nodes::Filter.new(call, condition.to_arel(table, model))
end