lib/rom/http/relation.rb in rom-http-0.5.0 vs lib/rom/http/relation.rb in rom-http-0.6.0.rc1

- old
+ new

@@ -1,46 +1,123 @@ -require 'rom/plugins/relation/view' +require 'dry/core/cache' +require 'rom/initializer' require 'rom/plugins/relation/key_inference' +require 'rom/http/transformer' module ROM module HTTP # HTTP-specific relation extensions # class Relation < ROM::Relation + extend Dry::Core::Cache + extend ::ROM::Initializer include Enumerable adapter :http - use :view use :key_inference + option :transformer, reader: true, default: proc { ::ROM::HTTP::Transformer } + forward :with_request_method, :with_path, :append_path, :with_options, - :with_params, :clear_params, :project + :with_params, :clear_params - # @api private + def initialize(*) super - if schema? - dataset.response_transformer( - Dataset::ResponseTransformers::Schemad.new(schema.to_h) - ) + + raise( + SchemaNotDefinedError, + "You must define a schema for #{self.class.register_as} relation" + ) unless schema? + end + + def primary_key + attribute = schema.find(&:primary_key?) + + if attribute + attribute.alias || attribute.name + else + :id end end + def project(*names) + with(schema: schema.project(*names.flatten)) + end + + def exclude(*names) + with(schema: schema.exclude(*names.flatten)) + end + + def rename(mapping) + with(schema: schema.rename(mapping)) + end + + def prefix(prefix) + with(schema: schema.prefix(prefix)) + end + + def wrap(prefix = dataset.name) + with(schema: schema.wrap(prefix)) + end + + def to_a + with_transformation { super } + end + # @see Dataset#insert def insert(*args) - dataset.insert(*args) + with_transformation { dataset.insert(*args) } end alias_method :<<, :insert # @see Dataset#update def update(*args) - dataset.update(*args) + with_transformation { dataset.update(*args) } end # @see Dataset#delete def delete dataset.delete + end + + private + + def with_transformation(&block) + tuples = block.call + + transformed = with_schema_proc do |proc| + transformer_proc[Array([tuples]).flatten(1).map(&proc.method(:call))] + end + + tuples.kind_of?(Array) ? transformed : transformed.first + end + + def with_schema_proc(&block) + schema_proc = fetch_or_store(schema) do + Types::Coercible::Hash.schema(schema.to_h) + end + + block.call(schema_proc) + end + + def transformer_proc + if mapped? + transformer[:map_array, transformer[:rename_keys, mapping]] + else + transformer[:identity] + end + end + + def mapped? + mapping.any? + end + + def mapping + schema.each_with_object({}) do |attr, mapping| + mapping[attr.name] = attr.alias if attr.alias + end end end end end