-
Notifications
You must be signed in to change notification settings - Fork 92
clean up and refactor active record container backend #543
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
clean up and refactor active record container backend #543
Conversation
0f9eab5 to
0afd7f8
Compare
|
Thanks for this! ❤️ Will review this week. |
ace21a7 to
e7e0b4d
Compare
|
I rebased everything and updated as requested:
One thing to keep in mind is that empty hashes might already exist in saved models if the container backend was used before this PR and it will not "self heal" (like it did with Edit: I did it as extra commits so you can follow it. I can squash all commits if everything is good at the end. |
e7e0b4d to
b47131f
Compare
b47131f to
b0613ae
Compare
|
Hey @shioyama, hope you're good! Any chance to review this PR again? I'd like to get this merged and off my list :-) If there are some changes needed I'll update the PR, just say so. (Edit: Just rebased it on master) |
fixes dirty tracking and creating empty translation hashes on read fixes shioyama#540
b0613ae to
1991ddf
Compare
|
@doits Thanks so much, this is a really great PR! ❤️
I think that's ok, if it hasn't been a problem so far then presumably it won't suddenly start being one (for those using the container backend). |
| def write(locale, value, _ = nil) | ||
| set_attribute_translation(locale, value) | ||
| model_translations(locale)[attribute] | ||
| read(locale) |
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.
hi guys :)
I think there's an issue here - the TLDR is that set_attribute_translation isn't touching the cache and if the cache has previously been inicialized (say with { en: nil }) , the read(locale) will always return nil and not the value that we JUST wrote
Loading development environment (Rails 8.0.1)
lovely-app(dev)> a = Badge.new
=>
#<Badge:0x00000001158dc4b0
...
lovely-app(dev)> a.title
=> nil
lovely-app(dev)> a.title = "aaa"
=> "aaa"
lovely-app(dev)> a.title
=> nil
```
of course if I *don't* call the reader before, it's fine
```ruby
Loading development environment (Rails 8.0.1)
lovely-app(dev)> a = Badge.new
=>
#<Badge:0x00000001168e41f0
...
lovely-app(dev)> a.title = "aaaaa"
=> "aaaaa"
lovely-app(dev)> a.title
=> "aaaaa"
```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.
the problem is - I think - the container#write calls read for it's return value, which ends up in cache#read -- that ends up returning the previous value (in this case nil) and .. deep breath .. the cache#write isn't given a chance to rewrite the cached value as it's always getting the same value it has :)
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.
What I don't understand is why call read when we have the value right there -- I'll look at the commits , maybe there's a hint
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.
a little background too, we've been using mobility for a while (years) and this particular model (Badge) uses the container backend and it has a validation in place -- in the process of upgrading to rails 8 I had to upgrade mobility (1.2.9 > 1.3.x) and specs started failing so I'm going down the rabbit hole
before opening an issue I wanted to come to grips with what might be happening and out of habit I decided to comment in place -- bad call maybe :)
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.
You are right this behaviour is wrong when cache plugin is used.
I guess I used read here just as a shortcut not to write it out what #read just above does. Which breaks when #read is overwritten by plugins, though!
And you are right value is never modified by this container backend. So it doesn't need to be reread after setting it and can be returned directly.
I added a test and implemented it in #671
Besides all this: Do you even need the cache plugin with the container backend? The container backend loads all data in a hash anyways when the model is loaded (or to be more precise active record loads it), so why the cache plugin?
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.
I really didn't need it, turns out we had it set as a default plugin in an initializer from way back when, I only noticed because specs started breaking when working on upgrading to rails 8 - which forced me to update mobility
I did turn it off and, kinda spoiler alert, there is another issue cropping up with mobility, but I want to dig into it and find out what it is first 😅
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.
Thank you @dramalho! We just went through the Rails 8 and Mobility 1.2.9 -> 1.3.2 upgrade, and this issue broke a lot of tests. We use the jsonb container back end and disabling the cache plugin (which, like you, we had left on by default) immediately solves the problem. This thread made finding and diagnosing painless.
fixes dirty tracking and creating empty translation hashes on read
fixes #540