Rails 7 adds ActiveRecord::Relation#excluding

Ashik Salman

By Ashik Salman

on March 16, 2021

This blog is part of our  Rails 7 series.

We might have used Array#excluding method to return an array after eliminating specific elements which are passed as an argument.

1=> ["John", "Sam", "Oliver"].excluding("Sam")
2=> ["John", "Oliver"]

When it comes to active record queries, we usually make use of NOT condition query to eliminate specific records from the result.

1=> users = User.where.not(id: current_user.id)
2=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" != 1"

This is simplified with Rails 7's newly-introduced ActiveRecord::Relation#excluding method.

1=> users = User.excluding(current_user)
2=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" != 1"
3
4# We can also pass a collection of records as an argument
5
6=> comments = Comment.excluding(current_user.comments)
7=> "SELECT \"comments\".* FROM \"comments\" WHERE \"comments\".\"id\" NOT IN (1, 2)"

The excluding method applies to activerecord association as well.

1=> comments = current_user.comments.excluding(comment1, comment2)
2=> "SELECT \"comments\".* FROM \"comments\" WHERE \"comments\".\"user_id\" = 1 AND \"comments\".\"id\" NOT IN (1, 2)"

The alias method without can also be used instead of excluding.

1=> users = User.without(current_user)
2=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" != 1"
3
4=> comments = Comment.without(comment1)
5=> "SELECT \"comments\".* FROM \"comments\" WHERE \"comments\".\"id\" != 1"

Check out these pull request 41439 & 41465 for more details.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.