@@ -194,10 +194,102 @@ def bind!(value)
194
194
self
195
195
end
196
196
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.
197
287
def where ( opts , *rest )
198
288
opts . blank? ? self : spawn . where! ( opts , *rest )
199
289
end
200
290
291
+ # #where! is identical to #where, except that instead of returning a new relation, it adds
292
+ # the condition to the existing relation.
201
293
def where! ( opts , *rest )
202
294
references! ( PredicateBuilder . references ( opts ) ) if Hash === opts
203
295
0 commit comments