Class: Praxis::Mapper::SelectorGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/praxis-mapper/selector_generator.rb

Overview

Generates a set of selectors given a resource and list of resource attributes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSelectorGenerator

Returns a new instance of SelectorGenerator.



7
8
9
10
11
# File 'lib/praxis-mapper/selector_generator.rb', line 7

def initialize
  @selectors = Hash.new do |hash, key|
    hash[key] = {select: Set.new, track: Set.new}
  end
end

Instance Attribute Details

#selectorsObject (readonly)

Returns the value of attribute selectors.



5
6
7
# File 'lib/praxis-mapper/selector_generator.rb', line 5

def selectors
  @selectors
end

Instance Method Details

#add(resource, fields) ⇒ Object



13
14
15
16
17
# File 'lib/praxis-mapper/selector_generator.rb', line 13

def add(resource, fields)
  fields.each do |name, field|
    map_property(resource, name, field)
  end
end

#add_association(resource, name, fields) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/praxis-mapper/selector_generator.rb', line 44

def add_association(resource, name, fields)
  association = resource.model.associations.fetch(name) do
    raise "missing association for #{resource} with name #{name}"
  end
  associated_resource = resource.model_map[association[:model]]

  case association[:type]
  when :many_to_one
    add_track(resource, name)
    add_select(resource, association[:key])
  when :one_to_many
    add_track(resource, name)
    add_select(associated_resource, association[:key])
  when :many_to_many
    head, *tail = association.fetch(:through) do
      raise "Association #{name} on #{resource.model} must specify the " +
        "':through' option. "
    end
    new_fields = tail.reverse.inject(fields) do |thing, step|
      {step => thing}
    end
    return add_association(resource, head, new_fields)
  else
    raise "no select applicable for #{association[:type].inspect}"
  end

  unless fields == true
    # recurse into the field
    add(associated_resource,fields)
  end
end

#add_property(resource, name) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/praxis-mapper/selector_generator.rb', line 76

def add_property(resource, name)
  dependencies = resource.properties[name][:dependencies]
  return if dependencies.nil?

  dependencies.each do |dependency|
    apply_dependency(resource, dependency)
  end
end

#add_select(resource, name) ⇒ Object



33
34
35
36
37
38
# File 'lib/praxis-mapper/selector_generator.rb', line 33

def add_select(resource, name)
  return select_all(resource) if name == :*
  return if selectors[resource.model][:select] == true

  selectors[resource.model][:select] << name
end

#add_track(resource, name) ⇒ Object



40
41
42
# File 'lib/praxis-mapper/selector_generator.rb', line 40

def add_track(resource, name)
  selectors[resource.model][:track] << name
end

#apply_dependency(resource, dependency) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/praxis-mapper/selector_generator.rb', line 85

def apply_dependency(resource, dependency)
  case dependency
  when Symbol
    map_property(resource, dependency, {})
  when String
    head, tail = dependency.split('.').collect(&:to_sym)
    raise "String dependencies can not be singular" if tail.nil?

    add_association(resource, head, {tail => true})
  end
end

#map_property(resource, name, field) ⇒ Object



23
24
25
26
27
28
29
30
31
# File 'lib/praxis-mapper/selector_generator.rb', line 23

def map_property(resource, name, field)
  if resource.properties.key?(name)
    add_property(resource, name)
  elsif resource.model.associations.key?(name)
    add_association(resource, name, field)
  else
    add_select(resource, name)
  end
end

#select_all(resource) ⇒ Object



19
20
21
# File 'lib/praxis-mapper/selector_generator.rb', line 19

def select_all(resource)
  selectors[resource.model][:select] = true
end