From 4e55265122215efe3e55a308d68f59d15270547d Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 2 Jul 2021 17:03:33 +0700 Subject: [PATCH 1/2] change translation classes to be destroyed --- .../backends/active_record/key_value.rb | 54 +++++++++++++++++-- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/mobility/backends/active_record/key_value.rb b/lib/mobility/backends/active_record/key_value.rb index 24e0b7f5..f2ac12c3 100644 --- a/lib/mobility/backends/active_record/key_value.rb +++ b/lib/mobility/backends/active_record/key_value.rb @@ -212,11 +212,55 @@ def visit_default(_) end end - setup do |attributes, _options, backend_class| - backend_class.define_has_many_association(self, attributes) - backend_class.define_initialize_dup(self) - backend_class.define_before_save_callback(self) - backend_class.define_after_destroy_callback(self) + setup do |attributes, options| + association_name = options[:association_name] + translation_class = options[:class_name] + key_column = options[:key_column] + value_column = options[:value_column] + belongs_to = options[:belongs_to] + + # Track all attributes for this association, so that we can limit the scope + # of keys for the association to only these attributes. We need to track the + # attributes assigned to the association in case this setup code is called + # multiple times, so we don't "forget" earlier attributes. + # + attrs_method_name = :"__#{association_name}_attributes" + association_attributes = (instance_variable_get(:"@#{attrs_method_name}") || []) + attributes + instance_variable_set(:"@#{attrs_method_name}", association_attributes) + + has_many association_name, ->{ where key_column => association_attributes }, + as: belongs_to, + class_name: translation_class.name, + inverse_of: belongs_to, + autosave: true + before_save do + send(association_name).select { |t| t.send(value_column).blank? }.each do |translation| + send(association_name).destroy(translation) + end + end + + module_name = "MobilityArKeyValue#{association_name.to_s.camelcase}" + unless const_defined?(module_name) + callback_methods = Module.new do + define_method :initialize_dup do |source| + super(source) + self.send("#{association_name}=", source.send(association_name).map(&:dup)) + # Set inverse on associations + send(association_name).each do |translation| + translation.send(:"#{belongs_to}=", self) + end + end + end + include const_set(module_name, callback_methods) + end + + # Ensure we only call after destroy hook once per translations class + translation_classes = [translation_class, *translation_class.descendants].uniq + after_destroy do + @mobility_after_destroy_translation_classes = [] unless defined?(@mobility_after_destroy_translation_classes) + (translation_classes - @mobility_after_destroy_translation_classes).each { |klass| klass.where(belongs_to => self).destroy_all } + @mobility_after_destroy_translation_classes += translation_classes + end end # Returns translation for a given locale, or builds one if none is present. From 50a0fc89a20bc5bbb1fe462345ed9e371502a032 Mon Sep 17 00:00:00 2001 From: Steven Hoang Date: Wed, 7 Dec 2022 11:03:11 +0700 Subject: [PATCH 2/2] change version to v1.3.1 --- lib/mobility/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mobility/version.rb b/lib/mobility/version.rb index b3275122..065de9ed 100644 --- a/lib/mobility/version.rb +++ b/lib/mobility/version.rb @@ -8,7 +8,7 @@ def self.gem_version module VERSION MAJOR = 1 MINOR = 3 - TINY = 0 + TINY = 1 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")