Skip to content

Instantly share code, notes, and snippets.

@asux
Created July 27, 2018 11:52
Show Gist options
  • Save asux/9a4455813fa5ff3aa79d07bebe39bc33 to your computer and use it in GitHub Desktop.
Save asux/9a4455813fa5ff3aa79d07bebe39bc33 to your computer and use it in GitHub Desktop.
SortCollection with Validated
# frozen_string_literal: true
module Bl
module Core
module Logic
class SortCollection
include Dry::Monads::Result::Mixin
include Dry::Monads::Validated::Mixin
include Dry::Monads::List::Mixin
include Dry::Monads::Do::All
ALLOWED_ORDER_BY = %i[created_at updated_at rating votes_count last_activity_date answers_count].freeze
ALLOWED_ORDER_DIRS = %i[asc desc].freeze
Schema = Dry::Validation.Schema do
configure do
predicates(Bl::Core::Logic::ActiveRecordPredicates)
end
required(:collection).filled(:orderable?)
end
OptionsSchema = Dry::Validation.Schema do
required(:order_by).value(included_in?: ALLOWED_ORDER_BY)
required(:order_dir).value(included_in?: ALLOWED_ORDER_DIRS)
end
def validate_input(input)
validation = Schema.call(input)
return Invalid(validation.errors) if validation.failure?
Success(input)
end
def validate_options(options)
validation = OptionsSchema.call(options)
return Invalid(validation.errors) if validation.failure?
Success(options)
end
def call(input, options = {})
return Success(input) if options.blank?
input, options = yield List::Validated[
validate_input(input),
validate_options(options)
].traverse.to_result
collection = input[:collection]
sorted = collection.order(options[:order_by] => options[:order_dir])
input[:collection] = sorted
Success(input)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment