Skip to content

Instantly share code, notes, and snippets.

@davidpelaez
Created March 3, 2016 16:10
Show Gist options
  • Save davidpelaez/acedec53229ab3841c52 to your computer and use it in GitHub Desktop.
Save davidpelaez/acedec53229ab3841c52 to your computer and use it in GitHub Desktop.
How to add custom steps to rom-mapper default Transproc processor. Useful to enhance the mapper with custom functionality and data transformations, e.g: lazy evaluation as presented in http://solnic.eu/2015/07/15/importing-data-with-rom-and-transproc.html
module Dataops
module Processors
class EnhancedAttributes < TransprocWithHook
BlockWrapper = Struct.new(:block) do
def call(*args)
self.block.call *args
end
end
ComputedAttribute = Class.new(BlockWrapper)
module Fns
extend Transproc::Registry
extend Transproc::Composer
import Transproc::Conditional
import Transproc::HashTransformations
import Transproc::ArrayTransformations
def self.resolve_as_computed(x)
-> atr { x.block.call(atr) }
end
def self.resolve_attribute(a)
t(:is, EnhancedAttributes::ComputedAttribute, t(:resolve_as_computed))[a]
end
def self.eval_values_with_self(value)
t(:eval_values, [value])[value]
end
def self.resolve_attributes(entity)
compose do |ops|
ops << Fns[:map_values, Fns[:resolve_attribute]]
ops << Fns[:eval_values_with_self]
end.call(entity)
end
end # Fns
def post_transformer
Fns[:resolve_attributes]
end
end # EnhancedAttributes
end # Processors
end # Dataops
module Dataops
class ExtendedMapper < ROM::Mapper
def self.build(header = self.header, processor = :enhancedattributes)
new(header, processor)
end
end
end # Dataops
module Dataops
module Processors
class TransprocWithHook < ROM::Processor::Transproc
def post_transformer
Transproc::Coercions[:identity]
end
def visit(atr, *args)
base_transformer = super(atr, *args)
base_transformer >> post_transformer if base_transformer
end
end
end # Processors
end # Dataops
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment