class Hat::RelationIncludes

Attributes

includes[RW]

Public Class Methods

from_params(params) click to toggle source
# File lib/hat/relation_includes.rb, line 19
def self.from_params(params)
  from_string(params[:include])
end
from_string(string) click to toggle source
# File lib/hat/relation_includes.rb, line 23
def self.from_string(string)
  return new if string.blank?

  includes_hash = build_hash_from_string(string)
  new(*flatten(includes_hash))
end
new(*includes) click to toggle source
Calls superclass method
# File lib/hat/relation_includes.rb, line 14
def initialize(*includes)
  @includes = includes.compact
  super(@includes)
end

Private Class Methods

build_hash_from_string(string) click to toggle source
# File lib/hat/relation_includes.rb, line 90
def self.build_hash_from_string(string)
  includes_hash = {}
  include_paths = string.split(',').map { |path| path.split('.') }

  include_paths.each do |path|
    current_hash = includes_hash
    path.each do |token|
      current_hash[token] ||= {}
      current_hash = current_hash[token]
    end
  end
  includes_hash
end
flatten(hash) click to toggle source

Turns this:

:tags, {images: [:comments]}, {reviews: [:author]}

Into this:

{
  tags: {},
  images: {
    comments: {}
  }
  reviews: {}
  }
}
# File lib/hat/relation_includes.rb, line 133
def self.flatten(hash)
  result = []
  hash.each do |k, v|
    if v.keys.size == 0
      result << k.to_sym
    else
      result << { "#{k}".to_sym => flatten(v) }
    end
  end
  result
end

Public Instance Methods

&(other_includes) click to toggle source
# File lib/hat/relation_includes.rb, line 45
def &(other_includes)
  hash = self.class.build_hash_from_string(to_s)
  other_hash = self.class.build_hash_from_string(other_includes.to_s)

  intersected_paths = (to_s.split(',') & other_includes.to_s.split(','))
  self.class.from_string(intersected_paths.join(','))
end
<=>(other_includes) click to toggle source
# File lib/hat/relation_includes.rb, line 53
def <=>(other_includes)
  to_s <=> other_includes.to_s
end
find(attr_name) click to toggle source
# File lib/hat/relation_includes.rb, line 66
def find(attr_name)
  includes.find do |relation|
    (relation.kind_of?(Symbol) && attr_name == relation) ||
      (relation.kind_of?(Hash) && relation.keys.include?(attr_name))
  end
end
for_query(serializer_class) click to toggle source

Return an expanded version of the includes for use in a query. This api is still pretty rough and likely to change

# File lib/hat/relation_includes.rb, line 82
def for_query(serializer_class)
  RelationIncludes.new(*ExpandedRelationIncludes.new(self, serializer_class))
end
include(additional_includes) click to toggle source
# File lib/hat/relation_includes.rb, line 57
def include(additional_includes)
  includes.concat(additional_includes)
  self
end
includes_relation?(attr_name) click to toggle source
# File lib/hat/relation_includes.rb, line 62
def includes_relation?(attr_name)
  find(attr_name).present?
end
nested_includes_for(attr_name) click to toggle source
# File lib/hat/relation_includes.rb, line 73
def nested_includes_for(attr_name)
  nested = find(attr_name)
  if nested.kind_of?(Hash)
    nested[attr_name]
  end
end
to_s() click to toggle source
# File lib/hat/relation_includes.rb, line 30
def to_s
  @to_s ||= begin
    paths = []
    includes.each do |item|
      if item.is_a? Hash
        stringify_keys(paths, item)
      else
        paths << [item]
      end
    end
    paths = paths.map { |p| p.join('.') }
    paths.sort.join(',')
  end
end

Private Instance Methods

stringify_keys(top_level_paths, hash, path_attrs = []) click to toggle source
# File lib/hat/relation_includes.rb, line 104
def stringify_keys(top_level_paths, hash, path_attrs = [])
  current_key = hash.keys.first
  path_attrs << current_key
  top_level_paths << path_attrs.dup

  hash[current_key].each do |path_value|
    if path_value.is_a? Hash
      path_attrs << stringify_keys(top_level_paths, path_value, path_attrs)
    else
      top_level_paths << (path_attrs.dup << path_value)
    end
  end
end