module Shamu::Services::RequestSupport
Include into services that support mutating resources to add basic {#with_request} and {Request} conventions.
Public Instance Methods
Used to interrogate the service for the {Request} class to use for a given method.
Combine with {Request#init_from} to prepare a request for use in a rails form ready to modify an existing entity.
@param [Symbol] method on the service that will be called. @return [Class] a class that inherits from Request
.
# File lib/shamu/services/request_support.rb, line 17 def request_class( method ) self.class.request_class( method ) end
Build a {Request} object, prepopulated with the current state of the resource to submit changes to the given `method`.
@param [Symbol] method that will be called with the generated request. @param [Entities::Entity] entity optional entity that will modified. @return [Request]
# File lib/shamu/services/request_support.rb, line 27 def request_for( method, entity = nil ) request = request_class( method ).new( entity ) request.id = entity.id if entity && request.attribute?( :id ) request end
Private Instance Methods
Support convenient calling convention on update/delete style methods that might pass an id and params or a single params hash with associated id.
@example
users.update user, name: "Changed" # Backend service users.update id: 1, name: "Changed" # HTTP request params
# File lib/shamu/services/request_support.rb, line 108 def extract_params( id, params ) if !params && !id.respond_to?( :to_model_id ) params, id = id, id[ :id ] || id[ "id" ] end if params params = params.symbolize_keys if params.respond_to?( :symbolize_keys ) params[ :id ] ||= id end [ id, params ] end
# File lib/shamu/services/request_support.rb, line 151 def request_class_by_alias( method ) candidate = case method when :new then "Create" when :edit then "Update" end if candidate && request_class_namespace.const_defined?( candidate ) request_class_namespace.const_get( candidate ) end end
# File lib/shamu/services/request_support.rb, line 146 def request_class_by_name( method ) camelized = method.to_s.camelize request_class_namespace.const_get( camelized ) if request_class_namespace.const_defined?( camelized ) end
# File lib/shamu/services/request_support.rb, line 163 def request_class_default request_class_namespace.const_get( "Change" ) if request_class_namespace.const_defined?( "Change" ) end
# File lib/shamu/services/request_support.rb, line 137 def request_class_namespace @request_class_namespace ||= ( name || "" ).sub( /(Service)?$/, "" ) .singularize .concat( "Request" ) .constantize rescue NameError self end
@!visibility public
Behaves the same as {#with_request} but always executes the block even if the params are not yet valid. Allows the block to populate the request with missing information before validating.
@param (see with_request
) @return (see with_request
) @see with_request
# File lib/shamu/services/request_support.rb, line 89 def with_partial_request( params, request_class, &block ) request = request_class.coerce( params ) sources = yield( request ) result = Result.coerce( sources, request: request ) request.complete( result.valid? ) recache_entity( result.entity ) if result.valid? && result.entity result end
@!visibility public
Respond to a {Request} returning a {Result} touple of the subject {Entities::Entity} and {Request}.
Before processing the `params` will be coerced and validated. If the request is invalid, the method will immediately return without yielding to the block.
If the block yields an {Entities::Entity} it will be assigned as the {Result#entity} in the returned {Result} object.
@param [Request,Hash] params of the request. @param [Class] request_class
to coerce `params` to. @yield (request) @yieldparam [Request] request coerced and validated from `params`. @yieldreturn [Entities::Entity,#errors] the entity manipulated during
the request or an object that responds to #errors.
@return [Result] @example
def process_order( params ) with_request params, ProcesOrderRequest do |request| order = Models::Order.find( request.id ) # Custom validation next request.error( :base, "can't do that" ) if order.state == 'processed' request.apply_to( order ) # If DB only validations fail, return errors next order unless order.save # All good, return an entity for the order scorpion.fetch OrderEntity, { order: order } end end
# File lib/shamu/services/request_support.rb, line 72 def with_request( params, request_class, &block ) with_partial_request params, request_class do |request, *args| next unless request.valid? yield request, *args end end