-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Some of RoR's hash conditions are implemented, others are not, and others are implemented differently. This issue is to decide on a consistent API for replicating these features.
From: https://guides.rubyonrails.org/active_record_querying.html#hash-conditions
- Range conditions is currently not implemented
Book.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
generates
SELECT * FROM books WHERE (books.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')
and
Book.where(created_at: (Time.now.midnight - 1.day)..)
generates
SELECT * FROM books WHERE books.created_at >= '2008-12-21 00:00:00'
2. Not conditions are implemented differently
RoR: Customer.where.not(orders_count: [1,3,5])
ActiveRecord:
Customer::not(orders_count: [1,3,5])
This is fine, unless we want not to support the negation of non-where clauses like:
Customer::having()->not(orders_count: [1,3,5])
which is not something RoR supports. Decided that it's not worth supporting.
- Nullable fields are not tested. I'm not sure if this works:
Customer.create!(nullable_contry: nil)
Customer.where.not(nullable_country: "UK")
=> []
# But
Customer.create!(nullable_contry: "UK")
Customer.where.not(nullable_country: nil)
=> [#<Customer id: 2, nullable_contry: "UK">]
- Or is not yet implemented
and neither is and:
RoR:Customer.where(last_name: 'Smith').or(Customer.where(orders_count: [1,3,5]))
RoR:Customer.where(last_name: 'Smith').and(Customer.where(orders_count: [1,3,5]))
But if we keep the API breakage theme with not()
, wouldn't this be better?
Customer::where(['last_name' => 'Smith'])->or(['orders_count' => [1,3,5])
But what about?
Customer::where(A)->or(B)->and(C)
is this A or (B and C)
or (A or B) and C
?
The advantage of RoR's implementation of or is that you can remove the ambiguity:
A or (B and C): Customer.where(A)->or(Customer::where(B)->where(C))
(A or B) and C: Customer.where(A)->or(Customer::where(B))->where(C)
But if you want to be consistent which RoR is not, and be able to negate OR'd and AND'ed clauses, then it should be:
Customer::not(Customer::where(A))
so you can do:
Customer::not(Customer::where(A)->or(Customer::where(B)->where(C)))
and perhaps:
Customer::not(Customer::having(A)->or(Customer::having(B)->having(C)))
if it's worth implementing. It's not.