Last active
October 6, 2017 23:07
-
-
Save KirillSuhodolov/6e02e7105406459be222fe4bb5808225 to your computer and use it in GitHub Desktop.
How I Learned to Stop Worrying and Love the Command Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# looks like command to Create/Update/Delete(Publish, Reject and etc) and Query object | |
class Post < ActiveRecord::Base | |
before_validate :build_from_template # if update don't run | |
before_create :check_content_uniq # extremely long time also don't run on update | |
after_update :send_notification # sometimes don't run | |
after_create :add_editor # sometimes don't run, can touch another record that has callbacks too :D | |
after_save :broadcast # sometimes don't run | |
after_create :run_indexing # sometimes don't run | |
private | |
def build_from_template | |
# ... | |
end | |
def check_content_uniq | |
# ... | |
end | |
def send_notification | |
# ... | |
end | |
def add_editor | |
# ... | |
# update another record, that run callbacks too :D | |
end | |
def broadcast | |
# ... | |
end | |
def run_indexing | |
# ... | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this variant even better than fat model | |
class Post < ActiveRecord::Base | |
end | |
Class OrderController < ApplicationController | |
def edit | |
# many lines of code there | |
end | |
def create | |
# many lines of code there | |
end | |
def publish | |
# many lines of code there | |
end | |
def reject | |
# many lines of code there | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EntityController < ApplicationController | |
def create | |
op = EntityOperation::Create.new(params, current_user) | |
op.process | |
if op.success? | |
render json: op.result, status: :created | |
else | |
render json: { errors: op.result.errors }, status: :unprocessable_entity | |
end | |
end | |
end | |
module EntityOperation | |
class Create < EventSequence::Sequence | |
class SequenceSerializer < EventSequence::Serializer | |
RECORD_FIELDS = %i(id name order_id).freeze | |
end | |
def build_record(params) | |
params | |
end | |
class ChecPermissionsEvent < EventSequence::Event | |
def process(record) | |
end | |
def should? | |
true | |
end | |
end | |
def create_order(record) | |
record.save && record | |
end | |
def refetch_order(record) | |
record.reload | |
end | |
def on_fail(e) | |
puts "FailEvent #{e}" | |
end | |
class BroadcastSequence < EventSequence::Sequence::Low | |
def broadcast(props) | |
BroadcastService.new(props).process | |
end | |
end | |
class NotifySequence < EventSequence::Sequence::Low | |
def notify(props) | |
NotificationService.new(props).process | |
end | |
end | |
class FeedSequece < EventSequence::Sequence::Low | |
def populate_feed(props) | |
ActivityFeedService.new(props).create | |
end | |
end | |
class AfterAllSequence < EventSequence::Sequence::Low | |
def call_me_after_all(props) | |
puts "#{call_me_after_all} props" | |
end | |
def on_fail_after_all(e) | |
puts "After all fail #{e}" | |
end | |
sequence({ | |
events: [:call_me_after_all], | |
fail: [:on_fail_after_all], | |
wait: [BroadcastSequence, FeedSequece, NotifySequence] | |
}) | |
end | |
sequence({ | |
events: [ | |
:build_record, | |
ChecPermissionsEvent, | |
:create_order, | |
:refetch_order, | |
BroadcastSequence, | |
FeedSequece, | |
NotifySequence, | |
AfterAllSequence, | |
], | |
serializer: SequenceSerializer, | |
fail: [:on_fail] | |
}) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Api | |
class OrdersController < ApiController | |
def create | |
if Order::Create.new(@order, current_user, order_params).process | |
render json: @order, status: :created | |
else | |
render json: { errors: @order.errors }, status: :unprocessable_entity | |
end | |
end | |
end | |
end | |
module Order | |
class Create < Operations::Create | |
class Runner < Operationable::Runners::Separate | |
def initialize_callbacks | |
push_to_queue(:broadcast, :notify, :populate_feed, queue: :low) | |
push_to_queue(:notify, queue: :high) | |
end | |
end | |
class Callback < ::Operations::Callback | |
def broadcast | |
BroadcastService.new(props).process | |
end | |
def notify | |
NotificationService.new(props).process | |
end | |
def populate_feed | |
ActivityFeedService.new(props).process | |
end | |
end | |
class Serializer < ::Operations::Serializer | |
RECORD_FIELDS = %i(id).freeze | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# How can somebody understand what is happend, and insure that circular calls not happens. | |
class One | |
include Pubsub | |
def make_something | |
# make something | |
if success? | |
publish(:one_finished, result) | |
else | |
publish(:one_failed, e) | |
end | |
end | |
end | |
One.subscribe(Two) | |
class Two | |
include Pubsub | |
def one_finished | |
# execute some code, and call another domain | |
publish(:call_three, result) | |
end | |
def one_failed | |
# execute some code, and call another domain | |
publish(:call_four, result) | |
end | |
end | |
Two.subscribe(Three, Four) | |
class Three | |
include Pubsub | |
def call_three | |
# may be publish for One? | |
end | |
end | |
class Four | |
include Pubsub | |
def call_four | |
# may be publish for Two? | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment