Class: Mobility::Backends::ActiveRecord::KeyValue
- Inherits:
-
Object
- Object
- Mobility::Backends::ActiveRecord::KeyValue
- Includes:
- Mobility::Backends::ActiveRecord, KeyValue
- Defined in:
- lib/mobility/backends/active_record/key_value.rb
Overview
Implements the KeyValue backend for ActiveRecord models.
Defined Under Namespace
Classes: StringTranslation, TextTranslation, Translation, Visitor
Backend Configuration collapse
Class Method Summary collapse
-
.apply_scope(relation, predicate, locale = Mobility.locale, invert: false) ⇒ ActiveRecord::Relation
Joins translations using either INNER/OUTER join appropriate to the query.
-
.build_node(attr, locale) ⇒ Mobility::Plugins::Arel::Attribute
Arel attribute for aliased translation table value column.
-
.define_after_destroy_callback(klass) ⇒ Object
Called from setup block.
-
.define_before_save_callback(klass) ⇒ Object
Called from setup block.
-
.define_has_many_association(klass, attributes) ⇒ Object
Called from setup block.
-
.define_initialize_dup(klass) ⇒ Object
Called from setup block.
Instance Method Summary collapse
-
#translation_for(locale) ⇒ Mobility::Backends::ActiveRecord::KeyValue::TextTranslation, Mobility::Backends::ActiveRecord::KeyValue::StringTranslation
Returns translation for a given locale, or builds one if none is present.
Methods included from KeyValue
#association_name, #class_name, #each_locale, #read, #write
Methods included from Mobility::Backends::ActiveRecord
Class Method Details
.apply_scope(relation, predicate, locale = Mobility.locale, invert: false) ⇒ ActiveRecord::Relation
Joins translations using either INNER/OUTER join appropriate to the query.
60 61 62 63 64 65 66 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 60 def apply_scope(relation, predicate, locale = Mobility.locale, invert: false) visitor = Visitor.new(self, locale) visitor.accept(predicate).inject(relation) do |rel, (attr, join_type)| join_type &&= ::Arel::Nodes::InnerJoin if invert join_translations(rel, attr, locale, join_type) end end |
.build_node(attr, locale) ⇒ Mobility::Plugins::Arel::Attribute
Returns Arel attribute for aliased translation table value column.
49 50 51 52 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 49 def build_node(attr, locale) aliased_table = class_name.arel_table.alias(table_alias(attr, locale)) Plugins::Arel::Attribute.new(aliased_table, value_column, locale, self, attr.to_sym) end |
.configure(options) ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 34 def configure() super if type = [:type] [:association_name] ||= :"#{options[:type]}_translations" [:class_name] ||= const_get("#{type.capitalize}Translation") end rescue NameError raise ArgumentError, "You must define a Mobility::Backends::ActiveRecord::KeyValue::#{type.capitalize}Translation class." end |
.define_after_destroy_callback(klass) ⇒ Object
Called from setup block. Can be overridden to customize behaviour.
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 118 def define_after_destroy_callback(klass) # Ensure we only call after destroy hook once per translations class b = self translation_classes = [class_name, *Mobility::Backends::ActiveRecord::KeyValue::Translation.descendants].uniq klass.after_destroy do @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 => self).destroy_all end @mobility_after_destroy_translation_classes += translation_classes end end |
.define_before_save_callback(klass) ⇒ Object
Called from setup block. Can be overridden to customize behaviour.
108 109 110 111 112 113 114 115 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 108 def define_before_save_callback(klass) b = self klass.before_save do send(b.association_name).select { |t| t.send(b.value_column).blank? }.each do |translation| send(b.association_name).destroy(translation) end end end |
.define_has_many_association(klass, attributes) ⇒ Object
Called from setup block. Can be overridden to customize behaviour.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 69 def define_has_many_association(klass, attributes) # 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) b = self klass.has_many association_name, ->{ where b.key_column => association_attributes }, as: belongs_to, class_name: class_name.name, inverse_of: belongs_to, autosave: true end |
.define_initialize_dup(klass) ⇒ Object
Called from setup block. Can be overridden to customize behaviour.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 89 def define_initialize_dup(klass) b = self 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("#{b.association_name}=", source.send(b.association_name).map(&:dup)) # Set inverse on associations send(b.association_name).each do |translation| translation.send(:"#{b.belongs_to}=", self) end end end klass.include const_set(module_name, callback_methods) end end |
Instance Method Details
#translation_for(locale) ⇒ Mobility::Backends::ActiveRecord::KeyValue::TextTranslation, Mobility::Backends::ActiveRecord::KeyValue::StringTranslation
Returns translation for a given locale, or builds one if none is present.
225 226 227 228 229 230 231 |
# File 'lib/mobility/backends/active_record/key_value.rb', line 225 def translation_for(locale, **) translation = translations.find do |t| t.send(key_column) == attribute && t.locale == locale.to_s end translation ||= translations.build(locale: locale, key_column => attribute) translation end |