-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Dirty plugin with Rails 6 (0-8-stable branch) #347
Conversation
In the past, Mobility has attempted to leverage ivar-backed dirty-tracking in ActiveModel and ActiveRecord, but this approach has become unsustainable since Rails has never openly supported this in ActiveRecord and now basically does not support it at all. Instead, we define a custom mutation tracker and override/define all necessary dirty methods explicitly. This requires more lines of code, but in the end it is easier to understand and reason about, and should be more robust to changes in Rails. By inlining the mutation tracker instead of trying to inherit from mutation tracker classes in ActiveModel, we are able to support all versions of Rails going as far as 4.2 with no conditionals.
d09d0cb
to
d04b821
Compare
From running this branch on my application, it looks like it introduces a bug with the For example, when using, 0.8.8, ["id", "starts_at", "ends_at", "created_at", "updated_at", ...., "title_en"] but on this branch it gives me ["title_en"] Using |
Oh that's not good! I'm surprised specs don't fail on that. I'll check up on it, thanks! |
Ok problem is here: mobility/lib/mobility/plugins/active_record/dirty.rb Lines 81 to 83 in d04b821
Neglected to merge |
I'm having another spec failing because |
Ah, that one I left out... but noticing now that it's public, so it should be implemented. I didn't do all the I guess I'll implement all the ones that are public. That will require more lines of code, more specs... ugh. I wish AM/AR were better designed for extension. |
Note that |
Aarg... |
These haven't been released yet...
ddeb567
to
39ea371
Compare
klass.attribute_method_matchers.map(&:suffix).select do |m| | ||
# only include suffixes for non-private handler methods | ||
m =~ /\A_/ && !klass.private_instance_methods.include?(:"attribute#{m}") | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pwim So in order to support all these attribute methods, I need to override them explicitly... which is really complicated because each version of Rails supports different methods. What I've done (which I was doing previously) is to figure out the methods by including ::ActiveModel::Dirty
into a class and then checking its suffixes... in this case though, I only want to define the ones that are public, which requires an extra check.
The result, though, is that at least we don't have a ton of conditionals in the code, just in the specs.
I could alternatively define the attribute_
methods and have the suffix methods call them, rather than the other way around... but in the end I don't think it really matters. Main thing is that tests cover all cases well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually not done yet... have to do the same for suffixes defined in ActiveRecord...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh rats, this doesn't even work actually. This would support article.attribute_changed?(:title)
, but previous behaviour was article.attribute_changed?(:title_en)
... need to rethink.
Ok, after thinking about this for a while, I think I know how to do everything in a way that is not horribly messy/unmaintainable.
I think with this approach, we can avoid most version conditionals in the code and keep it relatively clean. The complexity will be held in the mutation tracker, everything else just delegates to that. |
I'll make the changes to |
Going to close this and try with a new PR. |
This is a patch to the 0-8-stable branch of #343. The branches are far apart now, so this really has to be the last major change to 0.8.x.