Closed pfeiffer closed 1 year ago
@flavorjones Do you have thoughts on this implementation? (I think you are also pretty familiar with rails internals)
Coming up with the simplest solution that works well is the goal. Unfortunately, I am not sure that there is a simpler solution that will meet our needs.
I feel comfortable with most of this solution, but I do worry how supportable it will be for the active-hash collaborators
@pfeiffer does this potentially fix #271 as well, or is that different? (not asking to test, just asking if you think it may overlap that PR]
Yup, that issue would be addressed as well by this PR.
Thanks for taking the time to review this rather aged PR 😀
We've been running this in production for a while now, and I would love to see it merged.
I'll add some more context and reply to the individual review comments tomorrow. I'm aware that it's a major rewrite and not as surgical as the other PRs - I do however believe that it's the way to go and if I remember correctly (on my phone right now), all public interfaces are kept while the buggy and unexpected behaviors are fixed.
@pfeiffer sorry for the delay. I guess this is a big change, and probably intimidating, BUT... It feels so similar to what I remember of ActiveRecord internals, so it really isn't so bad.
I do need some feedback from another maintainer. This changes the approach to the problem and want to make sure others are comfortable with this alternate style.
I did notice that people were hoping for the smaller changes (there are a few PRs that all seem to be taking a whack at this issue).
@pfeiffer sorry for the delay. I guess this is a big change, and probably intimidating, BUT... It feels so similar to what I remember of ActiveRecord internals, so it really isn't so bad.
You're right - the patterns are lifted from ActiveRecord and it provides a similar interface for chaining and lazily-evaluating conditions on the scopes. Method names etc. are also lifted from AR to keep the code and patterns similar for developers familiar with Rails.
The general idea is to make relations returned by where(..)
, order(..)
, reorder(..)
, not(..)
etc. immutable, which is how AR also works. By doing so, it solves a lot of fundamental issues with the previous code and opens up for supporting the newer AR methods such as invert_where
, reorder
etc., which would be impossible to support with the existing code, as the scopes mutate the original collection of records.
I do need some feedback from another maintainer. This changes the approach to the problem and want to make sure others are comfortable with this alternate style.
I did notice that people were hoping for the smaller changes (there are a few PRs that all seem to be taking a whack at this issue).
I've seen that as well and contributed a few more surgical PRs as well as I see others have also been doing (#271, #266, #255, #261, #197). However, while these might fix the most obvious issues and bugs, they do not address the underlying issues of mutating scopes, and implementing eg. invert_where
would be close to impossible without a refactoring of the scopes like this.
Happy to jump on a chat or call to discuss if needed :-)
@flavorjones Do you find this approach reasonable? This will fix many of our outstanding issues around sorting and modifying data.
I like how it follows rails patterns but want a second opinion before I merge
Sorry, I've been underwater for a few days. I'll make time to read the code this week. I'm not an expert in Rails internals but I appreciate you asking for a gut check.
@kbrock No objections to merging this, sorry for not doing a more detailed review or getting back to you earlier.
This PR adresses the same issues as #266, #265, #257, #193 and #261 at once, by adressing the 'root' of the issue - namely the mutating methods on
Relation
.While #266 and #265 also adresses this in isolation, this PR is an alternative addressing the kinda messy structure of
Relation
andWhereChain
, by extracting the condition predicate matching to their ownCondition
class. The conditions are evaluated lazily when filtering on the records of a relation should happen.By doing it like this, it can open up for supporting more of the Rails scoping API such as
#reorder
and eg.#invert_where
. Both are included here in the PR.