where(*args) public

Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments.

#where accepts conditions in one of several formats. In the examples below, the resulting SQL is given as an illustration; the actual query generated may be different depending on the database adapter.


A single string, without additional arguments, is passed to the query constructor as an SQL fragment, and used in the where clause of the query.

Client.where("orders_count = '2'")
# SELECT * from clients where orders_count = '2';

Note that building your own string from user input may expose your application to injection attacks if not done properly. As an alternative, it is recommended to use one of the following methods.


If an array is passed, then the first element of the array is treated as a template, and the remaining elements are inserted into the template to generate the condition. Active Record takes care of building the query to avoid injection attacks, and will convert from the ruby type to the database type where needed. Elements are inserted into the string in the order in which they appear.

User.where(["name = ? and email = ?", "Joe", "joe@example.com"])
# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';

Alternatively, you can use named placeholders in the template, and pass a hash as the second element of the array. The names in the template are replaced with the corresponding values from the hash.

User.where(["name = :name and email = :email", { name: "Joe", email: "joe@example.com" }])
# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';

This can make for more readable code in complex queries.

Lastly, you can use sprintf-style % escapes in the template. This works slightly differently than the previous methods; you are responsible for ensuring that the values in the template are properly quoted. The values are passed to the connector for quoting, but the caller is responsible for ensuring they are enclosed in quotes in the resulting SQL. After quoting, the values are inserted using the same escapes as the Ruby core method +Kernel::sprintf+.

User.where(["name = '%s' and email = '%s'", "Joe", "joe@example.com"])
# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';

If #where is called with multiple arguments, these are treated as if they were passed as the elements of a single array.

User.where("name = :name and email = :email", { name: "Joe", email: "joe@example.com" })
# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';

When using strings to specify conditions, you can use any operator available from the database. While this provides the most flexibility, you can also unintentionally introduce dependencies on the underlying database. If your code is intended for general consumption, test with multiple database backends.


#where will also accept a hash condition, in which the keys are fields and the values are values to be searched for.

Fields can be symbols or strings. Values can be single values, arrays, or ranges.

User.where(name: "Joe", email: "joe@example.com")
# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'

User.where(name: ["Alice", "Bob"])
# SELECT * FROM users WHERE name IN ('Alice', 'Bob')

User.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
# SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000')

In the case of a belongs_to relationship, an association key can be used to specify the model if an ActiveRecord object is used as the value.

author = Author.find(1)

# The following queries will be equivalent:
Post.where(author: author)
Post.where(author_id: author)

This also works with polymorphic belongs_to relationships:

treasure = Treasure.create(name: 'gold coins')
treasure.price_estimates << PriceEstimate.create(price: 125)

# The following queries will be equivalent:
PriceEstimate.where(estimate_of: treasure)
PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure)

Hash conditions may also be specified in a tuple-like syntax. Hash keys may be an array of columns with an array of tuples as values.

Article.where([:author_id, :id] => [[15, 1], [15, 2]])
# SELECT * FROM articles WHERE author_id = 15 AND id = 1 OR author_id = 15 AND id = 2


If the relation is the result of a join, you may create a condition which uses any of the tables in the join. For string and array conditions, use the table name in the condition.

User.joins(:posts).where("posts.created_at < ?", Time.now)

For hash conditions, you can either use the table name in the key, or use a sub-hash.

User.joins(:posts).where("posts.published" => true)
User.joins(:posts).where(posts: { published: true })

No Argument

If no argument is passed, #where returns a new instance of WhereChain, that can be chained with WhereChain#not, WhereChain#missing, or WhereChain#associated.

Chaining with WhereChain#not:

User.where.not(name: "Jon")
# SELECT * FROM users WHERE name != 'Jon'

Chaining with WhereChain#associated:

# SELECT "posts".* FROM "posts"
# INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
# WHERE "authors"."id" IS NOT NULL

Chaining with WhereChain#missing:

# SELECT "posts".* FROM "posts"
# LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
# WHERE "authors"."id" IS NULL

Blank Condition

If the condition is any blank-ish object, then #where is a no-op and returns the current relation.

Show source
Register or log in to add new notes.
August 22, 2012 - (>= v3.0.0)
0 thanks

Rails Guides

There is an excellent guide on the use of this method located here:


June 26, 2013 - (v3.0.0 - v3.2.13)
0 thanks



# SELECT `users`.* FROM `users` WHERE (`users`.`id` != 1) AND (`users`.`name` IS NOT NULL)
 User.where.not(id: 1).where.not(name: nil)
December 3, 2013
0 thanks

usage examples

For detailed usage examples of where see “Conditions” under ActiveRecord::Base.