Created
August 22, 2012 20:42
-
-
Save mbriggs/3429145 to your computer and use it in GitHub Desktop.
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
| =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