Maintaining large application is always a pain for rails developer. Because the MVC scructure encourage developer to write business logics in controller and model. Therefore when application become bigger, usually it will result in Fat controller or All mighty model that have lots of business logics crumble all over the places. Extract those logic to another place is one of the solution, but how do we extract and where to extract is another problem.
Fortunately, Rails community already tried to solve this problem. There are lots of frameworks that provide an abstraction layer to hold the extracted business logics, Each one have different approach and different feature, choosing a framework that fulfill the needs is really hard. Therefore I created a sample application that used all the abstraction framework, to let everyone can compare and choose the abstraction framework easier.
Active Interaction is created by orgsync. inc, it provides an abstraction layer for business logic. Also with the feature like validation, filter, composition and error handling.
Decent exposure is created by hashrocket, rather than provide an abstraction layer, it is focus on simplify controller CRUD actions. It provides an expose helper for controller that can find, create and update model.
Interactor is created by collectiveidea, which provides an abstraction layer for business logics. It does not validate and filter paramter, everything is assign to context. It also has composition and callbacks features.
executed do |context| order = context.order order.assign_attributes(order_params(context)) order.state = Order::COMPLETED context.success = order.save end
defself.order_params(context) context.params.require(:order).permit([ :address, :card_number, :card_code, :card_month, :card_year ]) end end
Surrounded is created by saturnflyer, it provide the abstraction based on the role. It take parameter object and extend the objects with context specific methods, it’s an interesting approach.
Trialblazer is created by apotonick, it’s an ambitious framework that combine view layer abstraction: cell and model/controller layer abstraction: operation. It is the hardest one because in creates too many magic under the framework. and setting the framework is also problematic. But it provide a complete solution that include cell, which is a good view logic solution.
defcall(params) order = Order.find(params[:id]) order.assign_attributes(order_params(params)) order.state = Order::COMPLETED if order.save publish(:proceed_order_successful) else publish(:proceed_order_failed) end end
deforder_params(params) params.require(:order).permit([ :address, :card_number, :card_code, :card_month, :card_year ]) end end
classOrdersController < ApplicationController ...
defproceed proceed_order = ProceedOrder.new
proceed_order.on(:proceed_order_successful) do session[:order_id] = nil flash[:notice] = t('order.proceed') redirect_to root_path end
proceed_order.on(:proceed_order_failed) do render :checkout end
proceed_order.call(params) end end
Comparison
Features
ActiveInteraction
Decent Exposure
Interactor
Mutation
Light service
Surrunded
Trailblazer
Wisper
abstraction layer
x
x
x
x
x
x
x
validate input
x
x
x
x
validate output
x
composition
x
x
event notification
x
simplify crud
x
x
view layer
x
Hope this can help everyone find their abstraction framework.
My personal preference is Active Interaction (easy), Light service ( features ) or Surrounded (interesting) Trailblazer is hard to implement and understand the whole concept, but it is interesting too.
Comments