123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::Relation::WhereClause

Do not use. This class is for internal use only.
Relationships & Source Files
Inherits: Object
Defined in: activerecord/lib/active_record/relation/where_clause.rb

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(predicates) ⇒ WhereClause

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 10

def initialize(predicates)
  @predicates = predicates
end

Class Method Details

.empty

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 95

def self.empty
  @empty ||= new([]).freeze
end

Instance Attribute Details

#contradiction?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 99

def contradiction?
  predicates.any? do |x|
    case x
    when Arel::Nodes::In
      Array === x.right && x.right.empty?
    when Arel::Nodes::Equality
      x.right.respond_to?(:unboundable?) && x.right.unboundable?
    end
  end
end

#predicates (readonly, protected)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 117

attr_reader :predicates

Instance Method Details

#+(other)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 14

def +(other)
  WhereClause.new(predicates + other.predicates)
end

#-(other)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 18

def -(other)
  WhereClause.new(predicates - other.predicates)
end

#==(other) Also known as: #eql?

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 75

def ==(other)
  other.is_a?(WhereClause) &&
    predicates == other.predicates
end

#any?Boolean

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 8

delegate :any?, :empty?, to: :predicates

#ast

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 70

def ast
  predicates = predicates_with_wrapped_sql_literals
  predicates.one? ? predicates.first : Arel::Nodes::And.new(predicates)
end

#each_attributes (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 126

def each_attributes
  predicates.each do |node|
    attr = extract_attribute(node) || begin
      node.left if equality_node?(node) && node.left.is_a?(Arel::Predications)
    end

    yield attr, node if attr
  end
end

#empty?Boolean

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 8

delegate :any?, :empty?, to: :predicates

#eql?(other)

Alias for #==.

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 79

alias :eql? :==

#equalities(predicates, equality_only) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 145

def equalities(predicates, equality_only)
  equalities = []

  predicates.each do |node|
    if equality_only ? Arel::Nodes::Equality === node : equality_node?(node)
      equalities << node
    elsif node.is_a?(Arel::Nodes::And)
      equalities.concat equalities(node.children, equality_only)
    end
  end

  equalities
end

#equality_node?(node) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 159

def equality_node?(node)
  !node.is_a?(String) && node.equality?
end

#except(*columns)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 32

def except(*columns)
  WhereClause.new(except_predicates(columns))
end

#except_predicates(columns) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 174

def except_predicates(columns)
  attrs = columns.extract! { |node| node.is_a?(Arel::Attribute) }
  non_attrs = columns.extract! { |node| node.is_a?(Arel::Predications) }

  predicates.reject do |node|
    if !non_attrs.empty? && node.equality? && node.left.is_a?(Arel::Predications)
      non_attrs.include?(node.left)
    end || Arel.fetch_attribute(node) do |attr|
      attrs.include?(attr) || columns.include?(attr.name.to_s)
    end
  end
end

#extract_attribute(node) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 136

def extract_attribute(node)
  attr_node = nil
  Arel.fetch_attribute(node) do |attr|
    return if attr_node&.!= attr # all attr nodes should be the same
    attr_node = attr
  end
  attr_node
end

#extract_attributes

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 110

def extract_attributes
  attrs = []
  each_attributes { |attr, _| attrs << attr }
  attrs
end

#extract_node_value(node) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 209

def extract_node_value(node)
  if node.respond_to?(:value_before_type_cast)
    node.value_before_type_cast
  elsif Array === node
    node.map { |v| extract_node_value(v) }
  end
end

#hash

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 81

def hash
  [self.class, predicates].hash
end

#invert

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 85

def invert
  if predicates.size == 1
    inverted_predicates = [ invert_predicate(predicates.first) ]
  else
    inverted_predicates = [ Arel::Nodes::Not.new(ast) ]
  end

  WhereClause.new(inverted_predicates)
end

#invert_predicate(node) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 163

def invert_predicate(node)
  case node
  when NilClass
    raise ArgumentError, "Invalid argument for .where.not(), got nil."
  when String
    Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(node))
  else
    node.invert
  end
end

#merge(other)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 26

def merge(other)
  predicates = except_predicates(other.extract_attributes)

  WhereClause.new(predicates | other.predicates)
end

#non_empty_predicates (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 198

def non_empty_predicates
  predicates - ARRAY_WITH_EMPTY_STRING
end

#or(other)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 36

def or(other)
  left = self - other
  common = self - left
  right = other - common

  if left.empty? || right.empty?
    common
  else
    left = left.ast
    left = left.expr if left.is_a?(Arel::Nodes::Grouping)

    right = right.ast
    right = right.expr if right.is_a?(Arel::Nodes::Grouping)

    or_clause = if left.is_a?(Arel::Nodes::Or)
      Arel::Nodes::Or.new(left.children + [right])
    else
      Arel::Nodes::Or.new([left, right])
    end

    common.predicates << Arel::Nodes::Grouping.new(or_clause)
    common
  end
end

#predicates_with_wrapped_sql_literals (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 187

def predicates_with_wrapped_sql_literals
  non_empty_predicates.map do |node|
    case node
    when Arel::Nodes::SqlLiteral, ::String
      wrap_sql_literal(node)
    else node
    end
  end
end

#referenced_columns (protected)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 119

def referenced_columns
  hash = {}
  each_attributes { |attr, node| hash[attr] = node }
  hash
end

#to_h(table_name = nil, equality_only: false)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 61

def to_h(table_name = nil, equality_only: false)
  equalities(predicates, equality_only).each_with_object({}) do |node, hash|
    next if table_name&.!= node.left.relation.name
    name = node.left.name.to_s
    value = extract_node_value(node.right)
    hash[name] = value
  end
end

#wrap_sql_literal(node) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 202

def wrap_sql_literal(node)
  if ::String === node
    node = Arel.sql(node)
  end
  Arel::Nodes::Grouping.new(node)
end

#|(other)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/where_clause.rb', line 22

def |(other)
  WhereClause.new(predicates | other.predicates)
end