Skip to content

Instantly share code, notes, and snippets.

@bolshakov
Created December 22, 2017 15:19
Show Gist options
  • Save bolshakov/2f691243e1b93e66afb74d6a447835bb to your computer and use it in GitHub Desktop.
Save bolshakov/2f691243e1b93e66afb74d6a447835bb to your computer and use it in GitHub Desktop.
Active Action
# frozen_string_literal: true
require 'dry/validation'
require 'dry/core/class_attributes'
require 'active_action/action/params'
module ActiveAction
# This module provides validation logic for controller actions.
# @example
# class CreateUserAction
# include Action
# params do
# required(:name).filled(:str?)
# required(:email).filled(format?: EMAIL_REGEX)
# required(:age).maybe(:int?)
# end
#
# def perform(params)
# User.create(params)
# end
# end
module Action
include Fear::Either::Mixin
class << self
def included(base)
base.extend(Params)
end
end
# @param params [{Symbol => any}]
# @return [Fear::Right<any>, Fear::Left<{Symbol => <String>}>] returns +Fear::Right+ in
# case of successful validation or +Fear::Left+ in case of error.
#
def call(params)
validation_result = self.class.params.(params)
if validation_result.success?
Right(perform(validation_result.output))
else
Left(validation_result.messages)
end
end
# Template method to be overridden by an Action
# @param _params [{Symbol => any}]
# @return [<any>]
def perform(_params)
raise NotImplementedError
end
end
end
# frozen_string_literal: true
module ActiveAction
module Action
module Params
EMPTY_FORM = Dry::Validation.Form()
# Specify params validator
# @example
# class UpdateUsernameAction
# include Action
#
# params do
# required(:username).filled?(:str?)
# end
# end
#
# @see http://dry-rb.org/gems/dry-validation/forms/
def params(&block)
if block_given?
@params = Dry::Validation.Form(&block)
else
@params || EMPTY_FORM
end
end
end
end
end
# frozen_string_literal: true
require 'active_action/action'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment