class ActiveRecord::Relation

Public Instance Methods

with(opts, *rest) click to toggle source
# File lib/activerecord/cte/core_ext.rb, line 28
def with(opts, *rest)
  spawn.with!(opts, *rest)
end
with!(opts, *rest) click to toggle source
# File lib/activerecord/cte/core_ext.rb, line 32
def with!(opts, *rest)
  self.with_values += [opts] + rest
  self
end
with_values() click to toggle source
# File lib/activerecord/cte/core_ext.rb, line 37
def with_values
  @values[:with] || []
end
with_values=(values) click to toggle source
# File lib/activerecord/cte/core_ext.rb, line 41
def with_values=(values)
  raise ImmutableRelation if @loaded

  @values[:with] = values
end

Private Instance Methods

build_arel(*args) click to toggle source
Calls superclass method
# File lib/activerecord/cte/core_ext.rb, line 49
def build_arel(*args)
  arel = super
  build_with(arel) if @values[:with]
  arel
end
build_with(arel) click to toggle source
# File lib/activerecord/cte/core_ext.rb, line 55
def build_with(arel) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
  return if with_values.empty?

  recursive = with_values.delete(:recursive)
  with_statements = with_values.map do |with_value|
    case with_value
    when String then Arel::Nodes::SqlLiteral.new(with_value)
    when Arel::Nodes::As then with_value
    when Hash then build_with_value_from_hash(with_value)
    when Array then build_with_value_from_array(with_value)
    else
      raise ArgumentError, "Unsupported argument type: #{with_value} #{with_value.class}"
    end
  end

  recursive ? arel.with(:recursive, with_statements) : arel.with(with_statements)
end
build_with_value_from_array(array) click to toggle source
# File lib/activerecord/cte/core_ext.rb, line 73
def build_with_value_from_array(array)
  unless array.map(&:class).uniq == [Arel::Nodes::As]
    raise ArgumentError, "Unsupported argument type: #{array} #{array.class}"
  end

  array
end
build_with_value_from_hash(hash) click to toggle source
# File lib/activerecord/cte/core_ext.rb, line 81
def build_with_value_from_hash(hash) # rubocop:disable Metrics/MethodLength
  hash.map do |name, value|
    table = Arel::Table.new(name)
    expression = case value
                 when String then Arel::Nodes::SqlLiteral.new("(#{value})")
                 when ActiveRecord::Relation then value.arel
                 when Arel::SelectManager, Arel::Nodes::Union then value
                 else
                   raise ArgumentError, "Unsupported argument type: #{value} #{value.class}"
                 end
    Arel::Nodes::As.new(table, expression)
  end
end