Skip to content
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

Destroy all translations after model is destroyed (KeyValue backend) #15

Merged
merged 4 commits into from
Apr 2, 2017

Conversation

shioyama
Copy link
Owner

@shioyama shioyama commented Apr 2, 2017

This is a small but important change to ensure data integrity. When you translate a model using the KeyValue backend with some attribute, say title, then later decide to change the name of the attribute to something else, your earlier translations will disappear. This is natural since they were stored with the key title, and Mobility is now looking for a different key on the association.

This means that if you change your attribute name back, those earlier translations will again become available, because they were never destroyed (the change of attribute name was made at the code level, not the data level). I consider this a good thing.

However, currently they will also remain in the db even after you destroy the model, although translations with keys currently defined on the model will be destroyed. The reason is that there is a dependent: :destroy option on the translations association, but the association itself is limited with a where(key: attributes) scope. The scope is important for efficiency, to avoid looping through "dead" translations that are no longer used, but it also results in these translations not being seen as dependencies.

To fix this, I've added after destroy callbacks for ActiveRecord and Sequel which destroys all translations associated with this model, regardless of their key value. This means that provided you have at least one KeyValue attribute defined on the model when you destroy it, all translations will be destroyed as you would expect. I think this is reasonable and the best we can do.

shioyama added 3 commits April 2, 2017 11:08
The KeyValue backend uses a polymorphic association where key columns
store attributes, and we limit the association to only the keys defined
as translated attributes for the model (for performance, etc.) This has
the consequence that although we may have a dependent: destroy on the
model, translations which were previously stored with different keys
(for example, if we changed attribute names in the model) will be left
behind, because they are not seen by the association (anymore).

Having them left behind is unavoidable, but at minimum we should destroy
them all when the model is destroyed to avoid them begin associated with
other, new models. To do this we add an after destroy callback which
destroys *all* string and text translations associated with the model,
regardless of their attribute name (key). This ensures that when we
destroy a translated record, we are guaranteed that the entire record of
the record is wiped from the database.
@shioyama shioyama changed the title Destroy all translations after model is destroyed Destroy all translations after model is destroyed (KeyValue backend) Apr 2, 2017
@shioyama shioyama merged commit d0c0c41 into master Apr 2, 2017
@shioyama shioyama deployed to github-pages April 2, 2017 13:40 Active
@shioyama shioyama deleted the after_destroy branch April 2, 2017 13:40
@garshyn
Copy link

garshyn commented Aug 26, 2017

I have a model with acts_as_paranoid (paranoia gem) and Mobility modules included with KeyValue backend.

When a record is soft deleted, it remains in the database, but the translations are gone.

Is it possible to keep the translations?

@shioyama
Copy link
Owner Author

Hmm... well, this could easily be made an option for the KeyValue backend. Say:

class Post < ApplicationRecord
  translates :foo, dependent_destroy: false
end

Or something like this. Can you make a feature request (issue) for it?

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

Successfully merging this pull request may close these issues.

2 participants