Skip to content

Instantly share code, notes, and snippets.

@javierav
Last active April 6, 2022 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save javierav/0912a9f5dc6c82b2aea782b4fb389150 to your computer and use it in GitHub Desktop.
Save javierav/0912a9f5dc6c82b2aea782b4fb389150 to your computer and use it in GitHub Desktop.
class ApplicationAction
prepend Callable
def initialize(params={})
@params = params
@params.each_key do |key|
define_method(key) { @params[key] }
end
end
private
def create_resource(parent, attributes, ivar=nil, singleton: nil)
parent.send(singleton ? "create_#{singleton}" : 'create', attributes).tap do |resource|
instance_variable_set("@#{ivar}", resource) if ivar.present?
if resource.persisted?
yield resource if block_given?
success! resource: resource
else
failure! resource: resource, errors: resource.errors
end
end
end
def update_resource(resource, attributes)
resource.tap do
if resource.update(attributes)
yield resource if block_given?
success! resource: resource
else
failure! resource: resource, errors: resource.errors
end
end
end
def destroy_resource(resource)
resource.tap do
if resource.destroy
yield resource if block_given?
success! resource: resource
else
failure! resource: resource, errors: resource.errors
end
end
end
end
class ApplicationController < ActionController::Base
private
attr_reader :execution
def execute(action, params={})
@execution = action.new(params.reverse_merge(default_execute_params).call
end
def default_execute_params
{
actor: current_user
}
end
end
module Callable
def call
super
Result.new(@_action_status, @_action_response)
end
private
def success!(response={})
@_action_status = :success
@_action_response = response
end
def failure!(response={})
@_action_status = :failure
@_action_response = response
end
end
user:
updated:
success:
- users:self_updated # Users::SelfUpdatedNotification - esta notificación la recibe el propio usuario editado
- users:updated # Users::UpdatedNotification - esta notificación por ejemplo la recibe el responsable de ese usuario
class Result
def initialize(status, response)
@status = status.inquiry
@response = response
@response.each_key do |key|
define_method(key) { @response[key] }
end
end
def success?
@status.success?
end
def failure?
@status.failure?
end
end
class Users::Update < ApplicationAction
on :success, :send_email
event on: :success, resource: :user, target: -> { user.parent }, name: 'user:updated'
def call
update_resource(user, attributes)
end
def send_email
UserMailer.with(user: user).updated_to_user.delivery_later
end
end
class UsersController < ApplicationController
before_action :find_user
def update
execute Users::Update, user: @user, attributes: update_params
if execution.success?
redirect_to user_path(execution.resource)
else
render :edit, errors: execution.errors
end
end
private
def find_user
@user = User.find(params[:id])
end
def update_params
params.require(:user).permit(:first_name, :last_name)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment