class Mobility::Backends::ActiveRecord::KeyValue::Visitor

Internal class used to visit all nodes in a predicate clause and return a hash of key/value pairs corresponding to attributes (keys) and the respective join type (values) required for each attribute.

Example:

class Post < ApplicationRecord
  extend Mobility
  translates :title, :content, backend: :key_value
end

backend_class = Post.mobility_backend_class(:title)
visitor = Mobility::Backends::ActiveRecord::KeyValue::Visitor.new(backend_class, :en)

title   = backend_class.build_node("title", :en)   # arel node for title
content = backend_class.build_node("content", :en) # arel node for content

visitor.accept(title.eq("foo").and(content.eq(nil)))
#=> { title: Arel::Nodes::InnerJoin, content: Arel::Nodes::OuterJoin }

The title predicate has a non-nil value, so we can use an INNER JOIN, whereas we are searching for nil content, which requires an OUTER JOIN.

Private Instance Methods

visit_Arel_Nodes_Equality(object) click to toggle source
# File lib/mobility/backends/active_record/key_value.rb, line 122
def visit_Arel_Nodes_Equality(object)
  nils, nodes = [object.left, object.right].partition(&:nil?)
  if hash = visit_collection(nodes)
    hash.transform_values { nils.empty? ? INNER_JOIN : OUTER_JOIN }
  end
end
visit_Arel_Nodes_Or(object) click to toggle source
# File lib/mobility/backends/active_record/key_value.rb, line 136
def visit_Arel_Nodes_Or(object)
  [object.left, object.right].map(&method(:visit)).compact.inject(:merge).
    transform_values { OUTER_JOIN }
end
visit_Array(objects)
Alias for: visit_collection
visit_Mobility_Plugins_Arel_Attribute(object) click to toggle source
# File lib/mobility/backends/active_record/key_value.rb, line 141
def visit_Mobility_Plugins_Arel_Attribute(object)
  if object.backend_class == backend_class && object.locale == locale
    { object.attribute_name => OUTER_JOIN }
  end
end
visit_collection(objects) click to toggle source
# File lib/mobility/backends/active_record/key_value.rb, line 129
def visit_collection(objects)
  objects.map(&method(:visit)).compact.inject do |hash, visited|
    visited.merge(hash) { |_, old, new| old == INNER_JOIN ? old : new }
  end
end
Also aliased as: visit_Array
visit_default(_) click to toggle source
# File lib/mobility/backends/active_record/key_value.rb, line 147
def visit_default(_)
  {}
end