Created
February 8, 2013 23:44
-
-
Save krisleech/4742912 to your computer and use it in GitHub Desktop.
services and responders: which protocol (duck type) is best for talking between controller and service
This file contains hidden or 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 OrderController | |
def new | |
@order = Order.new | |
end | |
def create | |
command = CreateOrder.new(current_user, params[:order]) | |
command.execute(:success => lambda { redirect_to orders_path }, | |
:failure => lambda { |order| @order = order; render :action => :new }) | |
end | |
end | |
# Another example: | |
class OrderController | |
def new | |
@order = Order.new | |
end | |
def create | |
command = CreateOrder.new(current_user, params[:order]) | |
command.execute(:success => lambda { redirect_to orders_path }, | |
:failure => CreateFailure.new(self) | |
end | |
class CreateFailure < SimpleDelegator | |
def call(order) | |
@order = order | |
render :action => :new | |
end | |
end | |
end |
This file contains hidden or 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 OrdersController | |
def create | |
command = CreateOrder.new(current_user, params[:order]) | |
command.execute(CreateResponder.new(self)) | |
end | |
class CreateResponder < SimpleDelegator | |
def success(order) | |
redirect_to orders_path | |
end | |
def failure(order) | |
@order = order | |
render :action => :new | |
end | |
end | |
end |
This file contains hidden or 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 OrdersController | |
def new | |
@order = Order.new | |
end | |
def create | |
command = CreateOrder.new(current_user, params[:order]) | |
command.execute(OrderResponder.new(self)) | |
end | |
def edit | |
@order = current_user.orders.find(params[:id]) | |
end | |
def update | |
command = UpdateOrder.new(current_user, params[:order]) | |
command.execute(OrderResponder.new(self)) | |
end | |
class OrderResponder < SimpleDelegator | |
def create_successful(order) | |
redirect_to orders_path | |
end | |
def create_failed(order) | |
@order = order | |
render :action => :new | |
end | |
def update_successful(order) | |
flash[:notice] = 'Order updated' | |
redirect_to order_path(order) | |
end | |
def update_failed(order) | |
@order = order | |
render :action => :edit | |
end | |
end | |
end |
This file contains hidden or 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
# Matt Wynne-ish | |
def create | |
command = CreateOrder.new(self) | |
command.execute(current_user, params[:order]) | |
end | |
def order_create_successful(order) | |
redirect_to order_path(order) | |
end | |
def order_create_failed(order) | |
@order = order | |
render :action => :new | |
end | |
class CreateOrder | |
def initialize(listener) | |
@listener = listener | |
end | |
def execute(user, attributes) | |
order = Order.new(attributes) | |
order.created_by = user | |
if order.valid? | |
listener.order_create_successful(order) | |
else | |
listener.order_create_failed(order) | |
end | |
end | |
end |
This file contains hidden or 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
# stacking services (adapted from Matt Wynee) | |
def update | |
command = UpdateOrder.new(current_user, params[:order]) | |
command.execute(OrderResponder.new(WriteActivityFeed.new(self))) | |
end | |
class WriteActivityFeed < SimpleDelegator | |
def order_create_successful(order) | |
ActivityFeed.create(:order => order) | |
super(order) | |
end | |
end |
This file contains hidden or 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
# registering listeners | |
def create | |
command = CreateOrder.new | |
command.listeners << self | |
command.listeners << ActivityFeed.new | |
command.execute(current_user, params[:order]) | |
end | |
class CreateOrder | |
def listeners | |
@listeners ||= [] | |
end | |
def execute(user, attributes) | |
order = Order.new(attributes) | |
order.created_by = user | |
if order.valid? | |
order.save! | |
notify_listeners(:create_order_successful) | |
else | |
notify_listeners(:create_order_failed) | |
end | |
end | |
private | |
def notify_listeners(event, record) | |
listeners.each { |listener| listener.send(event, record) } | |
end | |
end | |
# Abstract reuseable elements | |
class CreateOrder | |
include ListenerNotifer | |
def execute(user, attributes) | |
# ... | |
end | |
end | |
module ListenerNotifier | |
def listeners | |
@listeners ||= [] | |
end | |
private | |
def notify_listeners(event, record) | |
listeners.each { |listener| listener.send(event, record) } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: multiple_listeners is now packaged as a gem: https://github.com/krisleech/wisper