Skip to content

Conversation

@doits
Copy link
Contributor

@doits doits commented Nov 5, 2021

fixes dirty tracking and creating empty translation hashes on read

fixes #540

@shioyama
Copy link
Owner

shioyama commented Nov 8, 2021

Thanks for this! ❤️ Will review this week.

@doits doits force-pushed the fix_ar_container_backend_change_on_read branch 2 times, most recently from ace21a7 to e7e0b4d Compare December 2, 2021 16:24
@doits
Copy link
Contributor Author

doits commented Dec 2, 2021

I rebased everything and updated as requested:

  • Always assume model[column_name] is a hash
  • No compact anymore
  • One spec about removing empty locale hashes when last attribute is deleted

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 compact). Not sure what to do about it though, or if there should be done anything about it.

Edit: I did it as extra commits so you can follow it. I can squash all commits if everything is good at the end.

@doits doits force-pushed the fix_ar_container_backend_change_on_read branch from e7e0b4d to b47131f Compare December 2, 2021 16:31
@doits doits requested a review from shioyama December 2, 2021 16:33
@doits doits force-pushed the fix_ar_container_backend_change_on_read branch from b47131f to b0613ae Compare December 2, 2021 16:40
@doits
Copy link
Contributor Author

doits commented Feb 27, 2022

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)

@doits doits force-pushed the fix_ar_container_backend_change_on_read branch from b0613ae to 1991ddf Compare February 27, 2022 22:08
@shioyama shioyama merged commit d75c88d into shioyama:master Feb 28, 2022
@shioyama
Copy link
Owner

@doits Thanks so much, this is a really great PR! ❤️

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 compact). Not sure what to do about it though, or if there should be done anything about it.

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)
Copy link

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"
```

Copy link

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 :)

Copy link

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

Copy link

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 :)

Copy link
Contributor Author

@doits doits Feb 9, 2025

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?

Copy link

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 😅

Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backend container reader mixes up dirty tracking and creates empty locale hash

4 participants