Skip to content

Commit 961cbcb

Browse files
Merge branch 'dp_docs'
Closes rails#6697
2 parents ab551be + dd9d874 commit 961cbcb

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

activerecord/lib/active_record/relation/query_methods.rb

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,102 @@ def bind!(value)
194194
self
195195
end
196196

197+
# Returns a new relation, which is the result of filtering the current relation
198+
# according to the conditions in the arguments.
199+
#
200+
# #where accepts conditions in one of several formats. In the examples below, the resulting
201+
# SQL is given as an illustration; the actual query generated may be different depending
202+
# on the database adapter.
203+
#
204+
# === string
205+
#
206+
# A single string, without additional arguments, is passed to the query
207+
# constructor as a SQL fragment, and used in the where clause of the query.
208+
#
209+
# Client.where("orders_count = '2'")
210+
# # SELECT * from clients where orders_count = '2';
211+
#
212+
# Note that building your own string from user input may expose your application
213+
# to injection attacks if not done properly. As an alternative, it is recommended
214+
# to use one of the following methods.
215+
#
216+
# === array
217+
#
218+
# If an array is passed, then the first element of the array is treated as a template, and
219+
# the remaining elements are inserted into the template to generate the condition.
220+
# Active Record takes care of building the query to avoid injection attacks, and will
221+
# convert from the ruby type to the database type where needed. Elements are inserted
222+
# into the string in the order in which they appear.
223+
#
224+
# User.where(["name = ? and email = ?", "Joe", "[email protected]"])
225+
# # SELECT * FROM users WHERE name = 'Joe' AND email = '[email protected]';
226+
#
227+
# Alternatively, you can use named placeholders in the template, and pass a hash as the
228+
# second element of the array. The names in the template are replaced with the corresponding
229+
# values from the hash.
230+
#
231+
# User.where(["name = :name and email = :email", { name: "Joe", email: "[email protected]" }])
232+
# # SELECT * FROM users WHERE name = 'Joe' AND email = '[email protected]';
233+
#
234+
# This can make for more readable code in complex queries.
235+
#
236+
# Lastly, you can use sprintf-style % escapes in the template. This works slightly differently
237+
# than the previous methods; you are responsible for ensuring that the values in the template
238+
# are properly quoted. The values are passed to the connector for quoting, but the caller
239+
# is responsible for ensuring they are enclosed in quotes in the resulting SQL. After quoting,
240+
# the values are inserted using the same escapes as the Ruby core method <tt>Kernel::sprintf</tt>.
241+
#
242+
# User.where(["name = '%s' and email = '%s'", "Joe", "[email protected]"])
243+
# # SELECT * FROM users WHERE name = 'Joe' AND email = '[email protected]';
244+
#
245+
# If #where is called with multiple arguments, these are treated as if they were passed as
246+
# the elements of a single array.
247+
#
248+
# User.where("name = :name and email = :email", { name: "Joe", email: "[email protected]" })
249+
# # SELECT * FROM users WHERE name = 'Joe' AND email = '[email protected]';
250+
#
251+
# When using strings to specify conditions, you can use any operator available from
252+
# the database. While this provides the most flexibility, you can also unintentionally introduce
253+
# dependencies on the underlying database. If your code is intended for general consumption,
254+
# test with multiple database backends.
255+
#
256+
# === hash
257+
#
258+
# #where will also accept a hash condition, in which the keys are fields and the values
259+
# are values to be searched for.
260+
#
261+
# Fields can be symbols or strings. Values can be single values, arrays, or ranges.
262+
#
263+
# User.where({ name: "Joe", email: "[email protected]" })
264+
# # SELECT * FROM users WHERE name = 'Joe' AND email = '[email protected]'
265+
#
266+
# User.where({ name: ["Alice", "Bob"]})
267+
# # SELECT * FROM users WHERE name IN ('Alice', 'Bob')
268+
#
269+
# User.where({ created_at: (Time.now.midnight - 1.day)..Time.now.midnight })
270+
# # SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000')
271+
#
272+
# === Joins
273+
#
274+
# If the relation is the result of a join, you may create a condition which uses any of the
275+
# tables in the join. For string and array conditions, use the table name in the condition.
276+
#
277+
# User.joins(:posts).where("posts.created_at < ?", Time.now)
278+
#
279+
# For hash conditions, you can either use the table name in the key, or use a sub-hash.
280+
#
281+
# User.joins(:posts).where({ "posts.published" => true })
282+
# User.joins(:posts).where({ :posts => { :published => true } })
283+
#
284+
# === empty condition
285+
#
286+
# If the condition returns true for blank?, then where is a no-op and returns the current relation.
197287
def where(opts, *rest)
198288
opts.blank? ? self : spawn.where!(opts, *rest)
199289
end
200290

291+
# #where! is identical to #where, except that instead of returning a new relation, it adds
292+
# the condition to the existing relation.
201293
def where!(opts, *rest)
202294
references!(PredicateBuilder.references(opts)) if Hash === opts
203295

0 commit comments

Comments
 (0)