-
Notifications
You must be signed in to change notification settings - Fork 213
Allow making operations on sifters and having them in a group #296
base: master
Are you sure you want to change the base?
Conversation
Alternatively you could just simply create a grouping inside the sifter, since it gets instance-evaled in the DSL. There could be cases where adding a grouping could be harmful, e.g. in SQL function evaluation. |
This doesn't work, still getting the error when doing the following: class User < ActiveRecord::Base
sifter(:my_sifter) { _(id + 5) }
end If only it was that simple... |
Oh right, it gets lazy-evaluated. I guess in that case the modules and operator aliases should be included in the sifter node? Like https://github.com/activerecord-hackery/squeel/blob/master/lib/squeel/nodes/grouping.rb#L6-22 My main concern is that always wrapping things in a grouping might break in some edge cases. |
I myself was more afraid of copying code from one place to another, felt safer to wrap with a grouping. I bet @ernie would have a much better idea on how to implement this |
Probably reasonable to include the operators on the sifters. I am trying to think of a situation in which (apart from a stylistic opposition to unnecessary parens) a user would actively want to avoid parentheses around the result of a sifter. If I can't come up with any, then it would make sense to update the visitor to wrap the result in an Arel grouping node, without putting a grouping node into the Squeel AST. |
Functions that take keyword operators as part of their syntax would explode with extra parens. Consider |
Bah. Good call, @the8472. So, I'd say the better option really would be to simply wrap the sifter in a grouping node inside the Squeel DSL itself, and do whatever comparisons you want to afterward, @odedniv. That wouldn't require any changes to Squeel and would make the intent more obvious in your own code (I think). |
@ernie, this means I have to wrap every use of that sifter with _(sift(...)), while grouping is not really what I wanted to achieve. I just want to be able to create a complicated equation in the model that I can later use anywhere. Example: class User < ActiveRecord::Base
sifter(:c) { a + b }
def c
a + b
end
end
User.where{sift(:c) == 5}.count
User.first.c == 5 I don't want the outside world to know how |
How is writing |
For the above example, I don't count I don't see a reason not to add the operator methods to Sifter, just like you have it for anything else (Literal etc). |
well, squeel is an AST-abstraction over SQL/Arel/active-record relations. It's still relatively close to the database. I don't think you should try to hide logic/pretend that it behaves like a regular column when it isn't. Of course you could monkey-patch some short-hand into the DSL that uses some operator character that's not in use or something like that. E.g. Another idea would be to make squeel aware of aliased columns in the select clause, that way you could write:
|
Operators don't work on sifters, so you always have to wrap them like so:
_(sift(:my_sifter))
.This is a patch I made that always returns the Sifter object wrapped withing Grouping.
Given the following model:
Here is some examples of the results before the patch:
Examples after the patch (and the expected result for the above examples):
Also, you can't have sifter within #group, so I added sifter visitation.
Before:
After: