Class: Mobility::Backends::Sequel::KeyValue
- Inherits:
-
Object
- Object
- Mobility::Backends::Sequel::KeyValue
- Includes:
- KeyValue, Mobility::Backends::Sequel, Util
- Defined in:
- lib/mobility/backends/sequel/key_value.rb
Overview
This backend requires the cache to be enabled in order to track and store changed translations, since Sequel does not support build
-type methods on associations like ActiveRecord.
Implements the KeyValue backend for Sequel models.
Defined Under Namespace
Modules: Cache Classes: CacheRequired, QualifiedIdentifier, StringTranslation, TextTranslation, Translatable
Constant Summary collapse
- Translation =
Translatable.new(:key, :value, :translatable)
Constants included from Util
Util::VALID_CONSTANT_NAME_REGEXP
Backend Configuration collapse
Class Method Summary collapse
- .build_op(attr, locale) ⇒ Object
-
.define_after_destroy_callback(klass) ⇒ Object
Called from setup block.
-
.define_one_to_many_association(klass, attributes) ⇒ Object
Called from setup block.
-
.define_save_callbacks(klass, attributes) ⇒ Object
Called from setup block.
-
.prepare_dataset(dataset, predicate, locale) ⇒ Sequel::Dataset
Prepared dataset.
Instance Method Summary collapse
-
#save_translations ⇒ Object
Saves translation which have been built and which have non-blank values.
-
#translation_for(locale) ⇒ Mobility::Backends::Sequel::KeyValue::TextTranslation, Mobility::Backends::Sequel::KeyValue::StringTranslation
Returns translation for a given locale, or initializes one if none is present.
Methods included from Util
#blank?, #camelize, #constantize, #demodulize, #foreign_key, included, #presence, #present?, #singularize, #underscore
Methods included from KeyValue
#association_name, #class_name, #each_locale, #read, #write
Methods included from Mobility::Backends::Sequel
Class Method Details
.build_op(attr, locale) ⇒ Object
40 41 42 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 40 def build_op(attr, locale) QualifiedIdentifier.new(table_alias(attr, locale), value_column, locale, self, attr) end |
.configure(options) ⇒ Object
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 28 def configure() raise CacheRequired, "Cache required for Sequel::KeyValue backend" if [:cache] == false super if type = [:type] [:association_name] ||= :"#{[:type]}_translations" [:class_name] ||= const_get("#{type.capitalize}Translation") end rescue NameError raise ArgumentError, "You must define a Mobility::Sequel::#{type.capitalize}Translation class." end |
.define_after_destroy_callback(klass) ⇒ Object
Called from setup block. Can be overridden to customize behaviour.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 96 def define_after_destroy_callback(klass) # Clean up *all* leftover translations of this model, only once. b = self translation_classes = [class_name, *Mobility::Backends::Sequel::KeyValue::Translation.descendants].uniq klass.define_method :after_destroy do super() @mobility_after_destroy_translation_classes = [] unless defined?(@mobility_after_destroy_translation_classes) (translation_classes - @mobility_after_destroy_translation_classes).each do |translation_class| translation_class.where(:"#{b.belongs_to}_id" => id, :"#{b.belongs_to}_type" => self.class.name).destroy end @mobility_after_destroy_translation_classes += translation_classes end end |
.define_one_to_many_association(klass, attributes) ⇒ Object
Called from setup block. Can be overridden to customize behaviour.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 55 def define_one_to_many_association(klass, attributes) belongs_to_id = :"#{belongs_to}_id" belongs_to_type = :"#{belongs_to}_type" # 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 = (klass.instance_variable_get(:"@#{attrs_method_name}") || []) + attributes klass.instance_variable_set(:"@#{attrs_method_name}", association_attributes) klass.one_to_many association_name, reciprocal: belongs_to, key: belongs_to_id, reciprocal_type: :one_to_many, conditions: { belongs_to_type => klass.to_s, key_column => association_attributes }, adder: proc { |translation| translation.update(belongs_to_id => pk, belongs_to_type => self.class.to_s) }, remover: proc { |translation| translation.update(belongs_to_id => nil, belongs_to_type => nil) }, clearer: proc { send_(:"#{association_name}_dataset").update(belongs_to_id => nil, belongs_to_type => nil) }, class: class_name end |
.define_save_callbacks(klass, attributes) ⇒ Object
Called from setup block. Can be overridden to customize behaviour.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 80 def define_save_callbacks(klass, attributes) b = self callback_methods = Module.new do define_method :before_save do super() send(b.association_name).select { |t| attributes.include?(t.__send__(b.key_column)) && Util.blank?(t.__send__(b.value_column)) }.each(&:destroy) end define_method :after_save do super() attributes.each { |attribute| mobility_backends[attribute].save_translations } end end klass.include callback_methods end |
.prepare_dataset(dataset, predicate, locale) ⇒ Sequel::Dataset
Returns Prepared dataset.
48 49 50 51 52 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 48 def prepare_dataset(dataset, predicate, locale) visit(predicate, locale).inject(dataset) do |ds, (attr, join_type)| join_translations(ds, attr, locale, join_type) end end |
Instance Method Details
#save_translations ⇒ Object
Saves translation which have been built and which have non-blank values.
202 203 204 205 206 207 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 202 def save_translations cache.each_value do |translation| next unless present?(translation.__send__ value_column) translation.id ? translation.save : model.send("add_#{singularize(association_name)}", translation) end end |
#translation_for(locale) ⇒ Mobility::Backends::Sequel::KeyValue::TextTranslation, Mobility::Backends::Sequel::KeyValue::StringTranslation
Returns translation for a given locale, or initializes one if none is present.
195 196 197 198 199 |
# File 'lib/mobility/backends/sequel/key_value.rb', line 195 def translation_for(locale, **) translation = model.send(association_name).find { |t| t.__send__(key_column) == attribute && t.locale == locale.to_s } translation ||= class_name.new(locale: locale, key_column => attribute) translation end |