I wrote this gem, GitHub - NullVoxPopuli/skinny_controllers: A pattern for allowing for easier testing of large projects' business logic
which is influenced by Trailblazer, but less with some different
opinions
here and there.
The main idea that it pulls out of trailblazer is operations and
policies.
Operations are in app/operations
Policies are in app/policies
Operations control what data you are getting, and Policies control if
you
are allowed to get it.
The goal is to have all the logic in ruby objects that don’t require a
controller instance to run (i.e. avoiding put/get/post in your tests).
At the very minimum, you’d need
include SkinnyControllers::Diet
# and then in your action
render json: model
and the rest is implicit.
obviously, not everyone wants the same create / update / destroy
functionality, so that can all be configured:
here is an example of the create
operation for the EventsController
module EventOperations
class Create < SkinnyControllers::Operation::Base
def run
return unless allowed?
# @model is used here, because the method `model` is memoized off
@model
@model = model_class.new(model_params)
@model.save
@model # or just `model`
end
end
end
allowed?
is a special method that looks up the corresponding policy:
class EventPolicy < SkinnyControllers::Policy::Base
# for the Create operation for the EventsController is matched to
create?
in the policy
# o / object here is the instance of the model trying to be created
def create?(o = object)
user.is_admin?
end
end
Thoughts?
I’m using this in a big side project I’ve been working on for event
registration. (Rails API + Ember)
example of operation specs:
https://github.com/NullVoxPopuli/aeonvera/blob/master/spec/operations/order_operations_spec.rb
example of policy specs:
https://github.com/NullVoxPopuli/aeonvera/blob/master/spec/policies/package_policy_spec.rb