Skip to content

Instantly share code, notes, and snippets.

@mbriggs
Created August 22, 2012 20:42
Show Gist options
  • Select an option

  • Save mbriggs/3429145 to your computer and use it in GitHub Desktop.

Select an option

Save mbriggs/3429145 to your computer and use it in GitHub Desktop.
=begin
We have a larger app, and we have (or are starting to have)
application services as facades to modules. When you have those,
a lot of the controller code becomes simple delegation. It would
be great to add a bit of sugar to make that delegation as painless
as regular controller methods.
Ideally, we would map from the router straight to our classes
(kind of like raptor style controllers). But since rails _really_
doesn't support that kind of thing, it would be nice if the controller
only really was there for mapping.
A nice effect of this approach would be that rails code is completely
isolated to the controller, making the service code testable and reusable.
It also provides a layer between REST concepts and the app code, which
don't nessicarily need to map 1:1.
=end
class FooController < ApplicationController
include ServiceDelegation
# since its a controller, normal rails patterns still work
def show
render 'show'
end
# able to delegate to different application services
delegate_to FooService do
# map the action to a service method.
# render :json => return value
map :create, render: :json
# pass a block, arg will be return value
# block gets executed in context of the controller
map :fromit do |successful|
if successful
render 'frommited'
else
render 'couldnt_fromit'
end
end
# be able to map controller method to different name
# if there is no param on the block, just execute it (don't crash)
map :destroy => :remove do
render :nothing # maybe render :nothing by default?
end
end
end
class FooService
# DI specific things (like current_user) into
# the service methods. if it is not in a list
# of specific things, assume it is part of the
# params hash (so foo will look for params[:foo])
# if it can't be found anywhere, send nil or raise?
# maybe map vs map! ?
def create(foo, current_user)
foo.merge!(created_by: current_user.id)
Foo.create(foo)
end
def fromit(id)
Foo.find(id).fromit
end
def remove(id)
Foo.destroy(id)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment