3 ms·
It may seem counter intuitive at first but here's the thing to understand: > users = User.where(:name => "david").limit(20) Does not actually do any calls or
by melvinram 16y ago
It may seem counter intuitive at first but here's the thing to understand:
> users = User.where(:name => "david").limit(20)
Does not actually do any calls or create any kind of sql by itself. When you follow it up by
> users.where("age > 29")
all you're telling the users object is that you want to add a condition to your next query. You are not telling it to refine the previous query.
To get what you want, you'd need to do:
> users = User.where(:name => "david").limit(20).all
> users.where("age > 29")
- Raphael_Amiard 16y agoWell, you could do it the django way, where you can't filter a queryset after a slice has been taken (eg. limit has been used) This is ten times more logical if you ask me.
- emmett 16y agoIt's very convenient to be able to pass a partially built query, including a limit, into a function which adds more conditions. Why would you not want to be able to do that?
- Raphael_Amiard 16y agoBecause the meaning of it is totally counter intuitive, for one ?
- viraptor 16y agoSure - I know how it works and that it's useful. Still - it breaks the no-surprise rule for me... You could always have stacking functions with both .where and .combine_where, so that: User.where(:name => "david").limit(20).where("age > 29") gives you (with second where starting new level of query): SELECT * FROM (SELECT * FROM user WHERE name = 'david' LIMIT 20) WHERE age > 29 and this (combine_where folding into the same expression): User.where(:name => "david").limit(20).combine_where("age > 29") gives you: SELECT * FROM user WHERE name = 'david' AND age > 29 LIMIT 20 Just like you don't expect `map()[range].map()` or whatever the equivalent in Ruby is, to combine the map calls and move the range to the end.