Skip to content
This repository
Browse code

Use ARel for Range Conditions section, remove Date & Time section bec…

…ause users should *never* do that.
  • Loading branch information...
commit 964c2025ff7b4d22902ed8ee86c3e2858a4cf3ba 1 parent 390de62
Ryan Bigg authored November 29, 2010
60  railties/guides/source/active_record_querying.textile
Source Rendered
@@ -65,6 +65,7 @@ The methods are:
65 65
 * +lock+
66 66
 * +readonly+
67 67
 * +from+
  68
+* +having+
68 69
 
69 70
 All of the above methods return an instance of <tt>ActiveRecord::Relation</tt>.
70 71
 
@@ -103,7 +104,7 @@ h5. +first+
103 104
 
104 105
 <ruby>
105 106
 client = Client.first
106  
-=> #<Client id: 1, first_name: => "Lifo">
  107
+=> #<Client id: 1, first_name: "Lifo">
107 108
 </ruby>
108 109
 
109 110
 SQL equivalent of the above is:
@@ -120,7 +121,7 @@ h5. +last+
120 121
 
121 122
 <ruby>
122 123
 client = Client.last
123  
-=> #<Client id: 221, first_name: => "Russel">
  124
+=> #<Client id: 221, first_name: "Russel">
124 125
 </ruby>
125 126
 
126 127
 SQL equivalent of the above is:
@@ -231,7 +232,7 @@ WARNING: Building your own conditions as pure strings can leave you vulnerable t
231 232
 
232 233
 h4. Array Conditions
233 234
 
234  
-Now what if that number could vary, say as an argument from somewhere, or perhaps from the user's level status somewhere? The find then becomes something like:
  235
+Now what if that number could vary, say as an argument from somewhere? The find then becomes something like:
235 236
 
236 237
 <ruby>
237 238
 Client.where("orders_count = ?", params[:orders])
@@ -279,62 +280,15 @@ h5(#array-range_conditions). Range Conditions
279 280
 If you're looking for a range inside of a table (for example, users created in a certain timeframe) you can use the conditions option coupled with the +IN+ SQL statement for this. If you had two dates coming in from a controller you could do something like this to look for a range:
280 281
 
281 282
 <ruby>
282  
-Client.where("created_at IN (?)",
283  
-  (params[:start_date].to_date)..(params[:end_date].to_date))
  283
+Client.where(:created_at => (params[:start_date].to_date)..(params[:end_date].to_date))
284 284
 </ruby>
285 285
 
286  
-This would generate the proper query which is great for small ranges but not so good for larger ranges. For example if you pass in a range of date objects spanning a year that's 365 (or possibly 366, depending on the year) strings it will attempt to match your field against.
  286
+This query will generate something similar to the following SQL:
287 287
 
288 288
 <sql>
289  
-SELECT * FROM users WHERE (created_at IN
290  
-  ('2007-12-31','2008-01-01','2008-01-02','2008-01-03','2008-01-04','2008-01-05',
291  
-  '2008-01-06','2008-01-07','2008-01-08','2008-01-09','2008-01-10','2008-01-11',
292  
-  '2008-01-12','2008-01-13','2008-01-14','2008-01-15','2008-01-16','2008-01-17',
293  
-  '2008-01-18','2008-01-19','2008-01-20','2008-01-21','2008-01-22','2008-01-23',...
294  
-  ‘2008-12-15','2008-12-16','2008-12-17','2008-12-18','2008-12-19','2008-12-20',
295  
-  '2008-12-21','2008-12-22','2008-12-23','2008-12-24','2008-12-25','2008-12-26',
296  
-  '2008-12-27','2008-12-28','2008-12-29','2008-12-30','2008-12-31'))
  289
+  SELECT "clients".* FROM "clients" WHERE ("clients"."created_at" BETWEEN '2010-09-29' AND '2010-11-30')
297 290
 </sql>
298 291
 
299  
-h5. Time and Date Conditions
300  
-
301  
-Things can get *really* messy if you pass in Time objects as it will attempt to compare your field to *every second* in that range:
302  
-
303  
-<ruby>
304  
-Client.where("created_at IN (?)",
305  
-  (params[:start_date].to_date.to_time)..(params[:end_date].to_date.to_time))
306  
-</ruby>
307  
-
308  
-<sql>
309  
-SELECT * FROM users WHERE (created_at IN
310  
-  ('2007-12-01 00:00:00', '2007-12-01 00:00:01' ...
311  
-  '2007-12-01 23:59:59', '2007-12-02 00:00:00'))
312  
-</sql>
313  
-
314  
-This could possibly cause your database server to raise an unexpected error, for example MySQL will throw back this error:
315  
-
316  
-<shell>
317  
-Got a packet bigger than 'max_allowed_packet' bytes: _query_
318  
-</shell>
319  
-
320  
-Where _query_ is the actual query used to get that error.
321  
-
322  
-In this example it would be better to use greater-than and less-than operators in SQL, like so:
323  
-
324  
-<ruby>
325  
-Client.where(
326  
-  "created_at > ? AND created_at < ?", params[:start_date], params[:end_date])
327  
-</ruby>
328  
-
329  
-You can also use the greater-than-or-equal-to and less-than-or-equal-to like this:
330  
-
331  
-<ruby>
332  
-Client.where(
333  
-  "created_at >= ? AND created_at <= ?", params[:start_date], params[:end_date])
334  
-</ruby>
335  
-
336  
-Just like in Ruby. If you want a shorter syntax be sure to check out the "Hash Conditions":#hash-conditions section later on in the guide.
337  
-
338 292
 h4. Hash Conditions
339 293
 
340 294
 Active Record also allows you to pass in hash conditions which can increase the readability of your conditions syntax. With hash conditions, you pass in a hash with keys of the fields you want conditionalised and the values of how you want to conditionalise them:

0 notes on commit 964c202

Please sign in to comment.
Something went wrong with that request. Please try again.