Class: ActiveRecord::Refined::AST::In

Inherits:
Predicate show all
Includes:
SetSubquery
Defined in:
lib/active_record/refined/ast.rb

Overview

IN for a list of values, BETWEEN for a range, IN (SELECT ...) for a relation.

Defined Under Namespace

Classes: QuotedRange

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Predicate

#!, #&, #|

Methods inherited from Node

#as, #asc, #desc

Constructor Details

#initialize(operand, values, negated: false) ⇒ In

Returns a new instance of In.



1890
1891
1892
1893
1894
# File 'lib/active_record/refined/ast.rb', line 1890

def initialize(operand, values, negated: false)
  @operand = operand
  @values = values
  @negated = negated
end

Instance Attribute Details

#negatedObject (readonly)

Returns the value of attribute negated.



1888
1889
1890
# File 'lib/active_record/refined/ast.rb', line 1888

def negated
  @negated
end

#operandObject (readonly)

Returns the value of attribute operand.



1888
1889
1890
# File 'lib/active_record/refined/ast.rb', line 1888

def operand
  @operand
end

#valuesObject (readonly)

Returns the value of attribute values.



1888
1889
1890
# File 'lib/active_record/refined/ast.rb', line 1888

def values
  @values
end

Instance Method Details

#to_arel(table, model) ⇒ Object



1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
# File 'lib/active_record/refined/ast.rb', line 1896

def to_arel(table, model)
  arel_operand = to_arel_operand(operand, table, model)
  case values
  when Range, QuotedRange
    lower = quote_value(values.begin, table, model)
    upper = quote_value(values.end, table, model)
    if json_between?(model) && lower && upper && !negated
      return arel_operand.gteq(lower).and(
        values.exclude_end? ? arel_operand.lt(upper) : arel_operand.lteq(upper))
    end
    range = QuotedRange.new(lower, upper, values.exclude_end?)
    arel_operand.public_send(negated ? :not_between : :between, range)
  when ActiveRecord::Relation
    arel_operand.public_send(negated ? :not_in : :in, set_subquery(values, "IN"))
  else
    arg = values
    if arg.is_a?(::Array)
      arg = arg.map { |value| quote_value(value, table, model) }
      return json_list(arel_operand, arg) if json_list?(model)
    end
    arel_operand.public_send(negated ? :not_in : :in, arg)
  end
end