Toolbelt for Ruby

Build Status Code Climate Code Coverage

A collection of POROs to use in your applications.

Why?

The objects contained within this library represent the most common types of objects used in our Ruby and Rails applications. They exist to keep models and controllers thin and make our domain logic easy to test. Additionally, including these base objects in a library makes re-use clean and simple, eliminating a lot of the boilerplate/duplicate that has historically existed in our applications.

What's Included?

There are several kinds of objects included in this library. They include:

  • Service
  • Policy

Installation

gem install toolbelt

or in your Gemfile

gem 'toolbelt'

Usage

Make sure you require the library.

require 'toolbelt'

Service Objects

Service objects should be used any time you want to abstract an operating that does something. That something can be a write to the database, sending of email, retrieval of data from an API, etc. These objects accept a hash of options and only require that you implement a single method, #call. The class method .call exists as a convenience so you can write MyService.call instead of MyService.new.call.

class CreateWidgetService < Toolbelt::Service
  def call
    widget = Widget.new(:name => options.name)
    if widget.save
      AdminMailer.new_widget_notification.deliver
    else
      AdminMailer.widget_creation_error_notification.deliver
    end
  end
end

CreateWidgetService.call(:name => 'FooBar')

Policy Objects

Policy objects exist to encapsulate business logic that needs to be verified within your application. These objects accept a hash of options and only require that you implement a single method #pass?. For scenarios when you want to ask the policy if it's failing, a #fail? method exists which simply returns the inverse of #pass?. There are corresponding class methods .pass? and .fail? for your convenience as well.

class ValidWidgetPolicy < Toolbelt::Service
  def call
    Widget.new(options).valid?
  end
end

ValidWidgetPolicy.pass?(:name => 'FooBar')
# => true
ValidWidgetPolicy.fail?(:name => 'FooBar')
# => false

Credit

Many of the concepts this library uses are beautifully explained in the following articles:

Contributing to toolbelt

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
  • Fork the project
  • Start a feature/bugfix branch
  • Commit and push until you are happy with your contribution
  • Make sure to add tests for it. This is important so we don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so we can cherry-pick around it.

Copyright (c) 2014 PJ Kelly (Crush & Lovely). See LICENSE for further details.