Class: ActiveMappers::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/active_mappers.rb

Constant Summary collapse

@@renderers =
{}
@@initial_renderers =
{}
@@scopes =
{}

Class Method Summary collapse

Class Method Details

.acts_as_polymorphObject



55
56
57
58
59
60
61
62
# File 'lib/active_mappers.rb', line 55

def self.acts_as_polymorph
  each do |resource|
    mapper = KeyTransformer.resource_to_mapper(resource, self)
    mapper.with(resource, rootless: true)
  rescue NameError
    raise NotImplementedError, 'No mapper found for this type of resource'
  end
end

.all(collection) ⇒ Object



112
113
114
# File 'lib/active_mappers.rb', line 112

def self.all(collection)
  collection.map { |el| one(el) }.compact
end

.attributes(*params) ⇒ Object



13
14
15
16
17
18
19
20
21
# File 'lib/active_mappers.rb', line 13

def self.attributes(*params)
  each do |resource|
    h = {}
    params.each do |param|
      h[param] = resource.try(param)
    end
    h
  end
end

.delegate(*params) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/active_mappers.rb', line 23

def self.delegate(*params)
  delegator = params.last[:to]
  params.pop
  each do |resource|
    h = {}
    params.each do |param|
      h[param] = delegator.to_s.split('.').inject(resource, :try).try(param)
    end
    h
  end
end

.each(&block) ⇒ Object



64
65
66
# File 'lib/active_mappers.rb', line 64

def self.each(&block)
  @@renderers[name] = (@@renderers[name] || []) << block
end

.evaluate_scopes(scope_name) ⇒ Object



80
81
82
83
84
85
86
87
88
# File 'lib/active_mappers.rb', line 80

def self.evaluate_scopes(scope_name)
  return if scope_name.nil?
  @@initial_renderers[name] = @@initial_renderers[name] ? @@initial_renderers[name] : [] + (@@renderers[name] || [])
  
  found_scope = (@@scopes[name] || []).detect { |s| s[:name] === scope_name }
  raise "ActiveMappers [#{name}] Scope named #{scope_name} has not been declared or is not a block" if found_scope.nil? || found_scope[:lambda].nil? || !found_scope[:lambda].respond_to?(:call)
  
  found_scope[:lambda].call
end

.one(resource) ⇒ Object



116
117
118
119
120
121
122
123
124
# File 'lib/active_mappers.rb', line 116

def self.one(resource)
  return nil unless resource
  return {} if @@renderers[name].nil? # Mapper is empty
  renderers = @@renderers[name].map do |renderer|
    renderer.call(resource)
  end.reduce(&:merge)

  KeyTransformer.format_keys(renderers)
end

.polymorphic(key) ⇒ Object



48
49
50
51
52
53
# File 'lib/active_mappers.rb', line 48

def self.polymorphic(key)
  each do |resource|
    resource_mapper = "#{KeyTransformer.base_namespace(self)}::#{resource.send("#{key}_type")}Mapper".constantize
    { key => resource_mapper.with(resource.send(key), rootless: true) }
  end
end

.relation(key, mapper = nil, **options) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/active_mappers.rb', line 35

def self.relation(key, mapper = nil, **options)
  path = options[:optional_path] || key
  each do |resource|
    relation_class_name = resource.class&.reflect_on_association(options[:optional_path] || key)&.class_name
    raise "undefined relation : #{key.to_s}" if (mapper.nil? && relation_class_name.nil?)

    mapper_to_use = mapper || KeyTransformer.resource_class_to_mapper(relation_class_name, self)       
    raise "'#{mapper_to_use.name}' should be a mapper" unless mapper_to_use.ancestors.map(&:to_s).include?("ActiveMappers::Base")
    
    { key => mapper_to_use.with(path.to_s.split('.').inject(resource, :try), options.merge(rootless: true)) }
  end
end

.render_with_root(args, options = {}) ⇒ Object



101
102
103
104
105
106
107
108
109
110
# File 'lib/active_mappers.rb', line 101

def self.render_with_root(args, options = {})
  resource_name = options[:root]
  resource_name ||= KeyTransformer.apply_on(self.name)
  
  if args.respond_to?(:each)
    { resource_name.to_s.pluralize.to_sym => all(args) }
  else
    { resource_name.to_s.singularize.to_sym => one(args) }
  end
end

.reset_renderers_before_scopesObject



126
127
128
129
# File 'lib/active_mappers.rb', line 126

def self.reset_renderers_before_scopes
  return if !@@initial_renderers || !@@initial_renderers[name]
  @@renderers[name] = @@initial_renderers[name].dup
end

.scope(*params, &block) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/active_mappers.rb', line 90

def self.scope(*params, &block)
  raise "ActiveMappers [#{name}] scope must be a bloc" if block.nil? || !block.respond_to?(:call)

  params.each do |param|
    @@scopes[name] = (@@scopes[name] || []) << {
      name: param,
      lambda: block,
    }
  end
end

.with(args, options = {}) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/active_mappers.rb', line 68

def self.with(args, options = {})
  evaluate_scopes(options[:scope])

  response = if options[:rootless]
    args.respond_to?(:each) ? all(args) : one(args)
  else
    render_with_root(args, options)
  end
  reset_renderers_before_scopes
  response
end