Add inequality methods gt, gte, lt, lte #8453

Closed
wants to merge 1 commit into
from

Projects

None yet

4 participants

@claudiob
Member
claudiob commented Dec 7, 2012

This commit allows Relation#where with no arguments to be chained
with new inequality query methods greater_than, greater_than_or_equal,
less_than, and less_than_or_equal, also aliased as gt, gte, lt,
and lte.

@claudiob claudiob Add inequality methods gt, gte, lt, lte
This commit allows `Relation#where` with no arguments to be chained
with new inequality query methods `greater_than`, `greater_than_or_equal`,
`less_than`, and `less_than_or_equal`, also aliased as `gt`, `gte`, `lt`,
and `lte`.
b883ff1

👍 Thanks for this! The sooner I don't have to use squeel the better, and this is the only reason I use it.

Member

I don't know enough about AR to comment on the implementation, but neat!

Owner
dhh commented Dec 7, 2012

No fan of this. where.greater_than_or_equal(age: 7) is worse than where("age > ?", 7) and gte is too obtuse. I don't think these cases are anywhere near as common as the #not case (which, btw, stands the comparison test: where.not(name: "David") is at least as good as where("name != ?", "David").

@dhh dhh closed this Dec 7, 2012
Member
claudiob commented Dec 7, 2012

@dhh I see your point. Would you be instead a fan of an or chainable method instead? Would you like this code?

User.where(['name = ?', 'Mike']).or(name: 'John', comments_count: 0).or('comments_count in (1,2)')

In my opinion, this would be a better way to write:

user = User.arel_table
User.where user[:name].eq('Mike').or(user[:name].eq('John').and user[:comments_count].eq(0)).or(user[:comments_count].in [1,2])

in order to obtain:

SELECT `users`.* FROM `users` WHERE (((`users`.`username` = 'Mike' OR `users`.`username` = 'John' AND `users`.`comments_count` = 0) OR `users`.`comments_count` IN (1, 2)))

What is your take on this?

Owner
dhh commented Dec 8, 2012

Claudio, the arel way is not the real comparison, this is:

User.where("(name = 'Mike') OR (name = 'John' AND comments_count = 0) OR (comments_count in (1,2))")

I'll try to look for some more examples in my code and see how the #or pattern fits. I'm not reflexively against it, but I want to be very careful expanding this line of api. It's so easy to seek completeness from a certain paradigm and then end up with something that's horrible to use in many common cases. IMO, most query dsls that try to completely map to SQL end up there.

On Dec 8, 2012, at 12:18 AM, Claudio B. wrote:

@dhh I see your point. Would you be instead a fan of an or chainable method instead? Would you like this code?

User.where(['name = ?', 'Mike']).or(name: 'John', comments_count: 0).or('comments_count in (1,2)')
In my opinion, this would be a better way to write:

user = User.arel_table
User.where user[:name].eq('Mike').or(user[:name].eq('John').and user[:comments_count].eq(0)).or(user[:comments_count].in [1,2])
in order to obtain:

SELECT users.* FROM users WHERE (((users.username = 'Mike' OR users.username = 'John' AND users.comments_count = 0) OR users.comments_count IN (1, 2)))
What is your take on this?


Reply to this email directly or view it on GitHub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment