class ActiveRecord::QueryMethods::WhereChain

Public Instance Methods

not(opts = :chain, *rest) click to toggle source

Returns a new relation expressing WHERE + NOT condition according to the conditions in the arguments.

User.where.not(name: nil)
# SELECT * FROM users WHERE users.name IS NOT NULL

If there is no argument, chain further.

User.where.not.gt(login_count: 3)
# SELECT * FROM users WHERE NOT(users.login_count > 3)

Note: This is the Active Record 4 version.

# File lib/active_record/where_chain_extensions_rails4.rb, line 20
def not(opts = :chain, *rest)
  where_value = @scope.send(:build_where, opts, rest).map do |rel|
    case rel
    when :chain
      @invert = true
      return self
    when NilClass
      raise ArgumentError, 'Invalid argument for .where.not(), got nil.'
    when Arel::Nodes::In
      Arel::Nodes::NotIn.new(rel.left, rel.right)
    when Arel::Nodes::Equality
      Arel::Nodes::NotEqual.new(rel.left, rel.right)
    when String
      Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(rel))
    else
      Arel::Nodes::Not.new(rel)
    end
  end

  @scope.references!(PredicateBuilder.references(opts)) if opts.is_a?(Hash)
  @scope.where_values += where_value
  @scope
end

Private Instance Methods

build_where_clause(new_predicate, old_where_clause) click to toggle source

Active Record 5.2 changed the API and removed binds method so we need to pass proper arguments to build a WHERE clause

# File lib/active_record/where_chain_extensions_rails5.rb, line 66
def build_where_clause(new_predicate, old_where_clause)
  if old_where_clause.respond_to?(:binds)
    Relation::WhereClause.new([new_predicate], old_where_clause.binds)
  else
    Relation::WhereClause.new([new_predicate])
  end
end
prepare_where(node_type, infix, opts, *rest) click to toggle source

Prepare the WHERE clause by inserting a proper Arel node and inverting it if necessary.

Note: This is the Active Record 4 version.

# File lib/active_record/where_chain_extensions_rails4.rb, line 50
def prepare_where(node_type, infix, opts, *rest)
  where_value = @scope.send(:build_where, opts, rest).map do |rel|
    if @invert
      Arel::Nodes::Not.new arel_node(node_type, infix, rel)
    else
      arel_node(node_type, infix, rel)
    end
  end
  @scope.where_values += where_value
  @scope
end
where_clause_factory_build(opts, rest = []) click to toggle source

Active Record 6.1 removed the where_clause_factory.build method method was replaced by build_where_clause

# File lib/active_record/where_chain_extensions_rails5.rb, line 76
def where_clause_factory_build(opts, rest = [])
  if ActiveRecord.version.release >= Gem::Version.new('6.1.0')
    @scope.send(:build_where_clause, opts, rest)
  else
    @scope.send(:where_clause_factory).build(opts, rest)
  end
end