Skip to content

Instantly share code, notes, and snippets.

@skwp
Last active December 15, 2015 18:09
Show Gist options
  • Save skwp/5302250 to your computer and use it in GitHub Desktop.
Save skwp/5302250 to your computer and use it in GitHub Desktop.
Hexagonal extraction of a controller action from reverb.com, showing reuse between controller and Grape/Roar based API. This is sample code stripped down to the essentials and is not guaranteed to work as-is :)
class Reverb::Actions::WatchListing
def self.watch(user, product, listener)
if product.owner?(user)
listener.failure(I18n.t('flash.watchlist.error_own'))
else
Reverb::Analytics.track(user, :watch_product) # FIXME, this doesn't belong here
user.user_watch_products.create(:product_id => product.id)
listener.success
end
end
end
module Reverb
class Wants < Grape::API
post '/wants' do
class WatchListingResponder < SimpleDelegator
def success
{"success" => true}
end
def failure(message)
error!({ "error" => message}, 412)
end
end
Reverb::Actions::WatchListing.watch(current_user, Product.find(params[:id]), WatchListingResponder.new(self))
end
end
end
class Dashboard::Buying::WatchedProductsController < Dashboard::BaseController
def create
product = Product.find(params[:id])
Reverb::Actions::WatchListing.watch(current_user, product, WatchListingResponder.new(self))
redirect_to product_url(product)
end
private
class WatchListingResponder < SimpleDelegator
def success
flash[:success] = "Listing has been added to #{link_to_watchlist}."
end
def failure(message)
flash[:error] = message
end
def link_to_watchlist
view_context.link_to 'your watchlist', dashboard_buying_watched_products_url
end
end
end
describe Dashboard::Buying::WatchedProductsController do
stub_user
let(:product) { mock('product', :id => 1) }
before { Product.stub(:find).with("1") { product } }
describe "#create" do
let(:responder) { Dashboard::Buying::WatchedProductsController::WatchListingResponder.new(subject) }
it "watches the listing" do
Reverb::Actions::WatchListing.should_receive(:watch).with(user, product, anything)
post :create, :id => product.id
response.should redirect_to product_url(product)
end
it "handles error display" do
responder.failure("foo")
flash[:error].should == "foo"
end
it "handles success display" do
responder.success
flash[:success].should =~ /Listing has been added to.*your watchlist.*/
end
end
end
@rinaldifonseca
Copy link

What about that approach: https://github.com/krisleech/wisper ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment