class Mobility::Backends::Sequel::KeyValue
Implements the {Mobility::Backends::KeyValue} backend for Sequel
models.
@note 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.
Constants
- Translation
Public Class Methods
@!endgroup
# 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
@!group Backend
Configuration @option (see Mobility::Backends::KeyValue::ClassMethods#configure
) @raise (see Mobility::Backends::KeyValue::ClassMethods#configure
) @raise [CacheRequired] if cache is disabled
# File lib/mobility/backends/sequel/key_value.rb, line 28 def configure(options) raise CacheRequired, "Cache required for Sequel::KeyValue backend" if options[:cache] == false super if type = options[:type] options[:association_name] ||= :"#{options[:type]}_translations" options[:class_name] ||= const_get("#{type.capitalize}Translation") end rescue NameError raise ArgumentError, "You must define a Mobility::Sequel::#{type.capitalize}Translation class." end
@param [Sequel::Dataset] dataset Dataset to prepare @param [Object] predicate Predicate @param [Symbol] locale Locale @return [Sequel::Dataset] Prepared dataset
# 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
Private Class Methods
# File lib/mobility/backends/sequel/key_value.rb, line 56 def join_translations(dataset, attr, locale, join_type) dataset.join_table(join_type, class_name.table_name, { key_column => attr.to_s, :locale => locale.to_s, :"#{belongs_to}_type" => model_class.name, :"#{belongs_to}_id" => ::Sequel[:"#{model_class.table_name}"][:id] }, table_alias: table_alias(attr, locale)) end
@return [Hash] Hash
of attribute/join_type pairs
# File lib/mobility/backends/sequel/key_value.rb, line 69 def visit(predicate, locale) case predicate when Array visit_collection(predicate, locale) when QualifiedIdentifier visit_sql_identifier(predicate, locale) when ::Sequel::SQL::BooleanExpression visit_boolean(predicate, locale) when ::Sequel::SQL::Expression visit(predicate.args, locale) else {} end end
# File lib/mobility/backends/sequel/key_value.rb, line 84 def visit_boolean(boolean, locale) if boolean.op == :IS nils, ops = boolean.args.partition(&:nil?) if hash = visit(ops, locale) join_type = nils.empty? ? :inner : :left_outer # TODO: simplify to hash.transform_values { join_type } when # support for Ruby 2.3 is deprecated ::Hash[hash.keys.map { |key| [key, join_type] }] else {} end elsif boolean.op == :'=' hash = visit(boolean.args, locale) # TODO: simplify to hash.transform_values { :inner } when # support for Ruby 2.3 is deprecated ::Hash[hash.keys.map { |key| [key, :inner] }] elsif boolean.op == :OR hash = boolean.args.map { |op| visit(op, locale) }. compact.inject(:merge) # TODO: simplify to hash.transform_values { :left_outer } when # support for Ruby 2.3 is deprecated ::Hash[hash.keys.map { |key| [key, :left_outer] }] else visit(boolean.args, locale) end end
# File lib/mobility/backends/sequel/key_value.rb, line 111 def visit_collection(collection, locale) collection.map { |p| visit(p, locale) }.compact.inject do |hash, visited| visited.merge(hash) { |_, old, new| old == :inner ? old : new } end end
# File lib/mobility/backends/sequel/key_value.rb, line 117 def visit_sql_identifier(identifier, locale) if identifier.backend_class == self && identifier.locale == locale { identifier.attribute_name => :left_outer } else {} end end
Public Instance Methods
Saves translation which have been built and which have non-blank values.
# File lib/mobility/backends/sequel/key_value.rb, line 193 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
Returns translation for a given locale, or initializes one if none is present. @param [Symbol] locale @return [Mobility::Backends::Sequel::KeyValue::TextTranslation,Mobility::Backends::Sequel::KeyValue::StringTranslation]
# File lib/mobility/backends/sequel/key_value.rb, line 186 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