Deadlift
Deadlift is a powerful gem that you should be using if you want to remove fat from your controllers and models.
Installation
Add this line to your application's Gemfile:
gem 'deadlift'
And then execute:
$ bundle
Or install it yourself as:
$ gem install deadlift
Usage
TODO: Write usage instructions here
What is this?
The concept here is to be able to refactor this example logic:
# ProductsController.rb
..
def create
@client = Product.new(product_params)
if @product.save
NotifyTechDepartment.new(@product.id).deliver
NotifyCEOAboutProductIncreaseMailer.new(@product.id).deliver
redirect_to @product
else
NotifyCEOAboutProductFailureMailer.new(@product.id).deliver
render "new"
end
end
..
private
def product_params
params.require[:product].permit(:name, :price, :brand, :category)
end
to:
def create
CreateProductDeadlift.new(params[:product])
.add_trainer(self) # report to self a.k.a. the controller
.add_trainer(NotifyCEOAboutProductIncrease.new)
.perform
end
def create_success(performance)
redirect_to performance.result
end
def create_failure(performance)
@client = performance.
render "new"
end
Note how we are not asking if the save is successful. We are simply performing a deadlift and setting what will happen if the deadlift is successful and what will happen if it fails.
When a deadlift is performed a Performance
object is passed to either create_success
or create_failure
depending on the deadlift's results.
You can then access the barbell again from the performance or the result itself, which in this case is the created product.
Also, we do not need strong parameters since this will be taken care of in the Barbell
stage
No pain, no gain!
Deadlifts
A deadlift is a fancy name for an Interactor which consists of all possible actions that should occur when performing it. Every deadlift needs a perform
method.
For instance, in the example above, when performing a deadlift (creating a product) I want to validate the passed in values, persist the product in the database and finally notify some tech-department that we have a new product in stock.
I'd define the deadlift like this:
# app/deadlifts/create_product_deadlift.rb
class CreateProductDeadlift < Deadlift::Base
# Reference a barbell!
def self.(params)
CreateProductBarbell.new(params)
end
def perform
perform_and_report_for_valid do
set_attributes
persist
notify_tech
end
end
private
def set_attributes
product.name = .name
product.price = .price
product.brand = .brand
product.category = .category
end
def persist
product.save
end
def notify_tech
NotifyTechDepartment.new(product.id).deliver
end
def product
@product ||= Product.new
end
# Setting what the result should be when calling performance.result
def result
product
end
end
Barbells
A barbell is a fancy name for a plain reform contract.
Obviously, to perform a deadlift you need a barbell.
The barbell is a reform object initialized with params
. If the barbell is present and valid then the Deadlift is performed.
# app/barbells/create_product_barbell.rb
class CreateProductBarbell < Deadlift::Barbell::Base
model :product
property :name
property :price
property :brand
property :category
validate :name, presence: true
validate :price, presence: true
validate :brand, presence: true
validate :category, presence: true
end
Trainers
You can add a trainer to any deadlift. The deadlift reports to the trainer when it is done, whether it has succeeded or failed. A trainer is a PORO that can do anything after a deadlift is performed.
# app/trainers/notify_ceo_about_product_increase.rb
class NotifyCeoAboutProductIncrease
def success(performance)
@absence = performance.result
NotifyCEOAboutProductIncreaseMailer.new(@absence.id).deliver
end
def failure(performance)
attrs = performance..attributes
NotifyCEOAboutProductFailureMailer.new(attrs: attrs).deliver
end
end
Performances
A performance is an object passed from the deadlift results.
You can ask the performance object for the #result
.
You can also ask for the barbell
object or the deadlift
if you somehow need it.
Development
After checking out the repo, run bundle install
to install dependencies. Then, run bundle exec rspec
to run the tests. You can also run bundle exec bin/console
for an interactive prompt that will allow you to experiment.
To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/karlingen/deadlift. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.