Skip to content

Instantly share code, notes, and snippets.

@serradura
Last active March 4, 2021 16:55
Show Gist options
  • Select an option

  • Save serradura/0f2dbba7f357d2054d4553530ef24e69 to your computer and use it in GitHub Desktop.

Select an option

Save serradura/0f2dbba7f357d2054d4553530ef24e69 to your computer and use it in GitHub Desktop.
ApplicationAction = ActiveModel::Attributes + Kind::Result
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'kind', git: 'https://github.com/serradura/kind', branch: 'main', require: false
gem 'activemodel', require: 'active_model'
end
require 'kind'
require 'kind/result'
require 'kind/validator'
class ApplicationAction
include ActiveModel::Model
include ActiveModel::Attributes
include Kind::Result::Methods
attribute :id
def self.call(input = nil)
new( Kind::Hash.empty_or(input) ).call
end
def self.to_proc
->(action) { ->(input) { action.call(input) } }.(self)
end
def call
raise NotImplementedError
end
end
class User
attr_reader :id, :name
def self.find_by(id:)
new(id, 'John Doe') if id
end
def initialize(id, name)
@id = id
@name = name
end
def update(params)
!!Kind::Try.presence(params[:name], :strip) { |name| @name = name }
end
def errors
OpenStruct.new(full_messages: ["Name can't be blank"])
end
end
class User
Find = ->(arg) do
input = Kind::Hash.empty_or(arg)
user = ::User.find_by(id: input[:id])
return Kind::Success(input.merge(user: user)) if user
Kind::Failure(message: "user not found")
end
end
class User::Update < ApplicationAction
attribute :user
attribute :user_params
validates :user, kind: User
validates :user_params, kind: Hash
def call
return Failure(errors: self.errors) if invalid?
return Success(:user_updated, user: user) if user.update(user_params)
return Failure(:user_cant_be_updated, user: user)
end
end
result =
{id: 1, user_params: { name: 'Serradura' }}
.then(&User::Find)
.then(&User::Update)
p result
# #<Kind::Success type=:user_updated value={:user=>#<User:0x00007ff8133d9d58 @id=1, @name="Serradura">}>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment